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

标签 swift core-data grand-central-dispatch nsfetchedresultscontroller nsmanagedobjectcontext

我尝试在大型核心数据库(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 是否正确? 我在核心数据实体中用于谓词的所有属性都是“索引”的,但在添加搜索文本时仍然有很多滞后

最佳答案

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

关于swift - 通过 searchBar 过滤 NSFetchedResultController 而不加载基本暂停?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40712137/

相关文章:

arrays - 如何将文件读入整数数组

ios - 在后台线程上下载图像时锁定核心数据

ios - 如何将纬度和经度存储在核心数据的表中

ios - 接收者类型 'xxx' 例如消息是前向声明

swift - 调度队列 - 嵌套、优化和控制

iphone - GCD 的后进先出堆栈?

ios - 使用导航 Controller 在滑出面板中显示右键

ios - 在 Swift 中将数组保存到文件

ios - View Controller 中的多个 uitableview 给出错误

ios - 为什么我不能停止 dispatch_async 串行队列中的计时器?