0

나는 UISearchBar를 가지고 있고 내베이스에 일부 필터를 추가하려고 시도하지만 새 조건부로 NSFetchedResultsController를 다시로드하려고 할 때 가끔 리로딩하는 데 약 10 초 (한 술부에 대해)가 포함되고 다른 시간에는이 한 술부에만 2 초가 포함됩니다. 술어에 사용 된 핵심 데이터의 모든 속성이 색인됩니다. 왜 이런 일이 벌어지고 어떻게 해결할 수 있습니까?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