filtering NSFetchedResultController via searchBar without loading base pauses?

泪湿孤枕 提交于 2019-12-25 08:18:39

问题


i try to create search in big Core Data base (32 thousand objects) but when i added some text to the UISearchBar i have some lags (because my base is updating with new search Predicate) how to fix this? how can i update my base in background thread?

fetchedResultController code

    lazy var context: NSManagedObjectContext = {
        let appDelegate = (UIApplication.shared.delegate as? AppDelegate)
        let context = appDelegate!.managedObjectContext
        return context//appDelegate!.managedObjectContext
    }()

    lazy var fetchedResultsController: NSFetchedResultsController<CardsBaseClass> = {
        let fetchRequest = NSFetchRequest<CardsBaseClass>(entityName: "CardsBase")
        let sortDescriptor = NSSortDescriptor(key: "cardName", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]

        fetchRequest.predicate = nil
        fetchRequest.fetchBatchSize = 50
        fetchRequest.returnsObjectsAsFaults = false

        //let mainContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext

        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }()

and add some child MOC for searching methods

    lazy var searchMOC: NSManagedObjectContext = {
        let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
        moc.parent = self.context
        return moc
    }()

for connecting fetchedResultController I use

override func viewDidAppear(_ animated: Bool) {
    self.view.gestureRecognizers?.removeAll()
    connectFetchedRequest()
}

func connectFetchedRequest() {
    indicatorLoad.startAnimating()
    context.perform({
        do {
            try self.fetchedResultsController.performFetch()
            DispatchQueue.main.async(execute: {
                self.tableView.reloadData()
                self.indicatorLoad.stopAnimating()
            })
        } catch {
            print(error)
        }
    })
}

search Predicates are updated with following code

    searchMOC.performAndWait({
        if searchText != "" {
            let predicate = NSPredicate(format: "\(self.searchPredicateName) contains[c] %@", searchText)
            predicateArray.append(predicate)
        }
        self.fetchedResultsController.fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
        do {
            try self.fetchedResultsController.performFetch()
            DispatchQueue.main.async(execute: {
                self.tableView.reloadData()
            })
        } catch {
            print(error)
        }
    })

Am I right to use searchMOC.perform and update the tableView via DispatchQueue? All my attributes which I use for Predicates in my Core Data Entity are "indexed", but I still have a lot of lags when added the search text


回答1:


You have to fetch in the child context, not the main context fetched results controller. Whatever you do in the FRC is on the main thread, but you want a background search.



来源:https://stackoverflow.com/questions/40712137/filtering-nsfetchedresultcontroller-via-searchbar-without-loading-base-pauses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!