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