通过 searchBar 过滤 NSFetchedResultController 而不加载基本暂停?

Posted

技术标签:

【中文标题】通过 searchBar 过滤 NSFetchedResultController 而不加载基本暂停?【英文标题】:filtering NSFetchedResultController via searchBar without loading base pauses? 【发布时间】:2016-11-21 03:03:23 【问题描述】:

我尝试在大型核心数据库(32000 个对象)中创建搜索,但是当我向UISearchBar 添加一些文本时,我有一些滞后(因为我的基础正在使用新的搜索谓词进行更新)如何解决这个问题?如何在后台线程中更新我的基础?

fetchedResultController 代码

    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
    ()

并添加一些子 MOC 用于搜索方法

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

用于连接我使用的 fetchedResultController

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)
        
    )

搜索谓词使用以下代码更新

    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)
        
    )

我可以使用 searchMOC.perform 并通过 DispatchQueue 更新 tableView 吗? 我在核心数据实体中用于谓词的所有属性都被“索引”了,但是在添加搜索文本时我仍然有很多滞后

【问题讨论】:

【参考方案1】:

您必须在子上下文中获取,而不是在主上下文中获取结果控制器。无论您在 FRC 中做什么都在主线程上,但您需要后台搜索。

【讨论】:

我用我的孩子 managedObjectContext 创建了一个新的 searchFetchedResultsController 并且也有这个问题。我实际上不明白,我也读过 NSAsynchronousFetchRequest 并且不知道如何解决我的问题 根据您发布的代码,您正在使用主要的前进 FRC。 我创建了后台 MOC,现在我的 fetchResultController 在后台加载,但现在我有新错误。 '无法在 -performFetch 之前访问获取的对象:'***.com/questions/40755273/…

以上是关于通过 searchBar 过滤 NSFetchedResultController 而不加载基本暂停?的主要内容,如果未能解决你的问题,请参考以下文章

Swift SearchBar 过滤和更新多个数组

UISearchResultsUpdating 不基于 searchBar 文本过滤 collectionView

searchBar 过滤 tableViewCells didSelectItemAt indexPath 显示在 navigationBar Title

SearchBar 过滤和调整 UITableView 单元格?

UIKit SearchBar 过滤 textDidChange 中的两个数组

将 SearchBar 添加到 uitableview 在过滤过程中遇到错误