我在使用NSBatchDeleteRequest后从NSFetchedResultsControllerDelegate获得准确更新时遇到问题,这些更改是作为更新类型而不是didChange委托方法上的删除类型。有没有办法让更改作为删除进入? (我有不同的删除与更新方案)。
删除请求: (使用调用者提供的私有上下文)
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)
}
}
印刷:
Have change with indexPath of: Optional([0, 0]), new index path of: Optional([0, 0]) for object: *my core data object*
update
答案 0 :(得分:6)
来自Apple的documentation:
批量删除比在代码中自己删除Core Data实体运行得更快,因为它们在SQL级别的持久性存储本身中运行。作为此差异的一部分,持久性存储上实现的更改不会反映在当前内存中的对象中。
执行批量删除后,删除内存中已从持久性存储中删除的所有对象。
有关处理NSBatchDeleteRequest
删除的对象的信息,请参阅Updating Your Application After Execution部分。
答案 1 :(得分:1)
由于cat sample.txt
label_annotations {
mid: "/m/01yrx"
description: "Cat"
score: 0.9895679950714111
topicality: 0.9895679950714111
}
label_annotations {
mid: "/m/0307l"
description: "Felidae"
score: 0.9541760087013245
topicality: 0.9541760087013245
}
label_annotations {
mid: "/m/01l7qd"
description: "Whiskers"
score: 0.953809380531311
topicality: 0.953809380531311
}
label_annotations {
mid: "/m/01k74n"
description: "Facial expression"
score: 0.9447915554046631
topicality: 0.9447915554046631
}
删除了persistentStore级别(在磁盘上)的托管对象,所以更新当前上下文(内存中)的最有效方法是通过在上下文上调用NSBatchDeleteRequest
,如下所示:
refreshAllObjects()
无需重新获取所有对象或func batchDelete() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
let context = appDelegate.persistentContainer.viewContext
if let request = self.fetchedResultsController.fetchRequest as? NSFetchRequest<NSFetchRequestResult> {
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: request)
do {
try context.execute(batchDeleteRequest) // performs the deletion
appDelegate.saveContext()
context.refreshAllObjects() // updates the fetchedResultsController
} catch {
print("Batch deletion failed.")
}
}
}
}
!
答案 2 :(得分: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("")
}
}