我有UISearchBar并尝试在我的基础中添加一些过滤器,但是当我尝试用新的谓词重新加载我的NSFetchedResultsController时,有时重新加载包含大约10秒(对于一个谓词),而在其他时间只有2秒用于这个谓词。在Predicates中使用的Core Data中的所有属性都被编入索引。 为什么会发生这种情况以及如何解决这个问题?
fetchResultController代码
lazy var context: NSManagedObjectContext = {
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)
return appDelegate!.managedObjectContext
}()
lazy var fetchedResultsController: NSFetchedResultsController<CardsBaseClass> = {
let fetchRequest = NSFetchRequest<CardsBaseClass>(entityName: "CardsBase")
let sortDescriptor = NSSortDescriptor(key: "cardName", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 50
fetchRequest.returnsObjectsAsFaults = false
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
UISearchBar方法
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
block?.cancel()
var predicateArray = predicateArrayClass.arrayOfPredicates
block = DispatchWorkItem {
let predicate = NSPredicate(format: "\(self.searchPredicateName) contains[c] %@", searchText)
predicateArray.append(predicate)
self.fetchedResultsController.fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
print(self.fetchedResultsController.fetchRequest.predicate)
self.connectFetchedRequest()
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: block!)
}
答案 0 :(得分:0)
您无法在后台线程上运行主线程Core Data托管对象上下文。
在Core Data中使用后台线程时,最好使用框架本身而不是GDC或DispatchQueue
API。核心数据提供了块API以及父和子上下文的概念。我认为在你的代码中你违反了这些API的主要原则:总是在自己的线程上运行不同的上下文,反之亦然:不要在多个线程上运行任何上下文。
我建议创建子上下文并使用performBlock
进行搜索。