0

我尝试在大型核心数据库(32万个对象)中创建搜索,但是当我向UISearchBar添加一些文本时,我有一些延迟(因为我的基础正在使用新搜索Predicate进行更新)如何解决此问题?我如何更新后台线程中的基础?通过searchBar过滤NSFetchedResultController而不加载基地暂停?

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

回答

0

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

+0

我创建一个新的searchFetchedResultsController与我的孩子managedObjectContext也有这个问题。 我实际上不明白,我也读了关于NSAsynchronousFetchRequest,并不知道如何解决我的问题 – Skie

+0

根据您发布的代码,您使用的是主FRC。 – Mundi

+0

我创建背景MOC,现在我的fetchResultController在后台加载,但现在我有新的错误。 '不能访问提取对象之前-performFetch:' http://stackoverflow.com/questions/40755273/how-can-i-cancel-block-with-fetchedresultscontroller-performfetch-and-stop-per – Skie