2

NSBatchDeleteRequest를 사용한 후 NSFetchedResultsControllerDelegate에서 정확한 업데이트를 얻는 데 문제가 있습니다. 변경 사항은 didChange 대리자 메서드의 삭제 유형이 아닌 업데이트 유형으로 전달됩니다. 변경 사항을 삭제로 가져 오는 방법이 있습니까? (삭제 대 업데이트에 대해 다른 시나리오가 있습니다.)NSBatchDeleteRequest를 사용하여 NSFetchedResultsController 사용

h 제 요청 : 가에

fileprivate class func deletePeopleWith(ids: Set<Int>, usingContext context: NSManagedObjectContext) { 

    let fr: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Person") 

    var predicates: [NSPredicate] = [] 
    ids.forEach { 

     predicates.append(NSPredicate(format: "id = %ld", $0)) 
    } 

    fr.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates) 

    let dr = NSBatchDeleteRequest(fetchRequest: fr) 
    dr.affectedStores = context.parent?.persistentStoreCoordinator?.persistentStores 

    do { 

     try context.parent?.execute(dr) 
     context.parent?.refreshAllObjects() 
     print("Deleting person") 

    } catch let error as NSError { 

     let desc = "Could not delete person with batch delete request, with error: \(error.localizedDescription)" 
     debugPrint(desc) 
    } 

} 

결과 (개인 호출자가 제공하는 컨텍스트를 사용) :

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 

    DispatchQueue.main.async { 

     let changeDesc = "Have change with indexPath of: \(indexPath), new index path of: \(newIndexPath) for object: \(anObject)" 
     var changeType = "" 
     switch type { 

     case .delete: 
      changeType = "delete" 

     case .insert: 
      changeType = "insert" 

     case .move: 
      changeType = "move" 

     case .update: 
      changeType = "update" 

     } 

     print(changeDesc) 
     print(changeType) 
    } 

} 

인쇄 : 애플의 documentation에서

Have change with indexPath of: Optional([0, 0]), new index path of: Optional([0, 0]) for object: *my core data object* 
update 
+0

부모 컨텍스트에서 삭제를 실행하고 제공된 개인 컨텍스트를 사용하여 삭제하려고한다고했습니다. – ELKA

+0

@ELKA 가져온 결과 컨트롤러는 부모 컨텍스트를 사용하여 만들어지며 부모 컨텍스트는 부모가 컨텍스트이기 때문에 레코드를 삭제해야하는 영구 저장소가됩니다. –

+0

그래서 context.parent는 NSFetchedResultController의 컨텍스트와 동일한 주 NSManagedObjectContext가됩니다. 옳은? – ELKA

답변

4

:

일괄 삭제는 SQL 수준에서 영구 저장소 자체에서 작동하므로 코드에서 핵심 데이터 엔터티를 직접 삭제하는 것보다 빠르게 실행됩니다. 이 차이점의 일부로 영구 저장소에서 제정 된 변경 사항은 현재 메모리에있는 개체에 반영되지 않습니다.

일괄 삭제가 실행 된 후에는 영구 저장소에서 삭제 된 메모리의 개체를 모두 제거하십시오.

NSBatchDeleteRequest에 의해 삭제 된 개체를 처리하는 방법은 Updating Your Application After Execution 섹션을 참조하십시오.

+0

문서만으로는 작동하지 않았지만 삭제 요청에서 결과 유형을 객체 ID로 업데이트 한 다음 가져온 결과 컨트롤러에서 사용하는 컨텍스트에서 모든 객체 새로 고침을 호출하면 변경 사항이 삭제됨으로 나타납니다! –

0

다음은 저에게 맞는 샘플입니다. 하지만 애니메이션으로 삭제를 업데이트하는 방법을 찾지 못했기 때문에 NSFetchedResultsControllerDelegate이 실행되지 않았습니다.

@IBAction func didPressDelete(_ sender: UIBarButtonItem) { 
     let managedObjectContext = persistentContainer.viewContext 
     let request = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: Record.self)) 
     let deleteRequest = NSBatchDeleteRequest(fetchRequest: request) 

     do { 
      // delete on persistance store level 
      try managedObjectContext.execute(deleteRequest) 

      // reload the whole context 
      managedObjectContext.reset() 
      try self.fetchedResultsController.performFetch() 
      tableV.reloadData() 
     } catch { 
      print("") 
     } 
    } 

Thanks.