0

私はUISearchBarを持っていて、ベースにいくつかのフィルタを追加しようとしましたが、新しい述語でNSFe​​tchedResultsControllerをリロードしようとすると、リロードに約10秒(1つの述語)が含まれます。述語で使用されるコアデータのすべての属性が索引付けされます。 なぜこれが起こって、これを修正するのですか?バックグラウンドスレッドで新しいフィルタ述語を使用してNSFetchedResultsControllerをリロードする方法は?

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

あなたはコアデータは、バックグラウンドスレッドでオブジェクトコンテキストを管理するメインスレッドを実行することはできません。

コアデータでバックグラウンドスレッドを使用する場合は、GDCまたはDispatchQueue APIではなく、フレームワーク自体を使用する方が良いです。コアデータは、ブロックAPIと親コンテキストと子コンテキストの概念を提供します。私はあなたのコードでは、これらのAPIの主な原則に違反していると思います。常にそのスレッドで別のコンテキストを実行してください。逆もまた同様です。複数のスレッドでコンテキストを実行しないでください。

子コンテキストを作成し、performBlockを使用して検索することをお勧めします。

+0

私はMOCの子供を追加しましたが、助けにならない、新しい質問を書くhttp://stackoverflow.com/questions/40712137/filtering-nsfetchedresultcontroller-via-searchbar-without-loading-base-pauses – Skie

関連する問題