我在删除后台线程上的几个对象时遇到了麻烦:
func delete(hierarchy: Hierarchy) throws {
// let backgroundThread = self.mainThread
let hierarchies = try self.hierarchies.reloadFrom(context: backgroundThread)
let hierarchy = try hierarchy.reloadFrom(context: backgroundThread)
let hierarchyModel = hierarchy.model!
// .. doing some checks ..
backgroundThread.performAndWait {
backgroundThread.delete(rootFile)
backgroundThread.delete(hierarchyModel)
for (index, model) in hierarchies.model!.hierarchies!.array.enumerated() {
let hierarchyModel = model as! HierarchyModel
hierarchyModel.position = Int32(index)
}
}
try backgroundThread.save()
}
然后循环执行:
func delete(hierarchies: [Hierarchy]) {
do {
for hierarchy in hierarchies {
try modelController.delete(hierarchy: hierarchy)
}
} catch {
NotificationCenter.default.post(FatalErrorNotification(error: error))
}
}
保存后,通常的NSFetchedResultsController调用其委托。请注意,他在mainThread上工作。
public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
print(indexPath, newIndexPath)
switch type {
case .insert:
// ...
case .delete:
tableView.removeRows(at: IndexSet(integer: indexPath!.item), withAnimation: .slideRight)
case .update:
// ...
case .move:
// ...
}
}
我使用mainThread.automaticallyMergeChangesFromParent
将backgroundThread更改为mainThread。到目前为止,这对我来说一直很好。
我的问题是在合并过程中会发生以下情况:
# Merging from background thread, delete order crashes.
Optional([0, 0]) nil
Optional([0, 1]) nil
Optional([0, 2]) nil
,在fetchedResultsController委托调用中崩溃之前。它在第三个调用时崩溃,仅剩下要删除的行[0,0]。因此它使应用程序崩溃。
如果我在mainThread上执行删除操作,则删除操作会依次进行:
# On mainThread: delete order works.
Optional([0, 0]) nil
Optional([0, 2]) Optional([0, 1])
Optional([0, 1]) Optional([0, 0])
going to end updates.
endUpdates
beginUpdates
Optional([0, 0]) nil
Optional([0, 1]) Optional([0, 0])
going to end updates.
endUpdates
beginUpdates
Optional([0, 0]) nil
going to end updates.
endUpdates
不会崩溃。我尝试过的:
更多收集的删除订单:
# On background thread: lucky.
beginUpdates
Optional([0, 2]) nil
Optional([0, 1]) nil
Optional([0, 0]) nil
going to end updates.
endUpdates
# On background thread: lucky again.
beginUpdates
Optional([0, 2]) nil
Optional([0, 1]) nil
Optional([0, 0]) nil
going to end updates.
endUpdates
# On background thread: unlucky again.
Optional([0, 1]) nil
Optional([0, 0]) nil
Optional([0, 2]) nil
# On background thread: unlucky again.
Optional([0, 0]) nil
Optional([0, 1]) nil
Optional([0, 2]) nil
# On background thread: unlucky on 2nd delete already.
beginUpdates
Optional([0, 1]) nil
Optional([0, 2]) nil
我希望有人可以帮助我解决此问题。真的很感激,我被困住了。
//
// NSFetchedResultsControllerDelegate
//
public func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
print("beginUpdates")
tableView.beginUpdates()
}
public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
print("going to end updates.")
tableView.endUpdates()
print("endUpdates")
}
答案 0 :(得分:0)
我想我已经找到问题了。您不能删除后台线程上的对象,然后对事物进行重新排序,然后期望删除按照与MainThread正确的顺序进行。