我有一段代码,它首先清空Core Data表,然后用新的和更新的数据填充它。此代码位于DispatchQueue.main.async
块内,该块在异步请求完成后发生。这是函数的相关代码。
这是我的代码:
let queue = OperationQueue()
let deleteOperation = BlockOperation {
let fetchRequest = Track.fetchRequest()
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
batchDeleteRequest.resultType = .resultTypeCount
do {
try self.managedObjectContext.execute(batchDeleteRequest)
self.managedObjectContext.reset()
}
catch {
fatalCoreDataError(error)
self.debug.log(tag: "RecentSessionsViewController", content: "Failed to delete cache")
return
}
}
let addOperation = BlockOperation {
for track in tempTracks {
let masterListEntry = NSEntityDescription.insertNewObject(forEntityName: "Track", into: self.managedObjectContext) as! Track
masterListEntry.id = track["id"] as! NSNumber
masterListEntry.name = track["name"] as! String
masterListEntry.comment = track["comment"] as! String
do {
try self.managedObjectContext.save()
self.trackMasterList.append(masterListEntry)
}
catch {
self.debug.log(tag: "RecentSessionsViewController", content: "Core data failed")
fatalError("Error: \(error)")
}
}
}
addOperation.addDependency(deleteOperation)
queue.addOperations([deleteOperation, addOperation], waitUntilFinished: false)
出于某种原因,我偶尔会在addOperation代码块上随机崩溃。在最近的崩溃中,触发了异常断点:
try self.managedObjectContext.save()
如果我点击继续,它再次落在这个断点上,然后当我再次点击继续时,它会崩溃显示汇编并出现此错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c70f34b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010bd5321e objc_exception_throw + 48
2 CoreFoundation 0x000000010c778265 +[NSException raise:format:] + 197
3 CoreFoundation 0x000000010c6a762b -[__NSCFSet addObject:] + 155
4 CoreData 0x000000010c2427ff -[NSManagedObjectContext(_NSInternalChangeProcessing) _processPendingUpdates:] + 399
5 CoreData 0x000000010c23cccd -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2445
6 CoreData 0x000000010c240e0c -[NSManagedObjectContext save:] + 412
7 AppName 0x000000010b0db7eb _TFFFFC8AppName28RecentSessionsViewController22refreshListFT_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_U_FT_T_U0_FT_T_ + 6459
8 AppName 0x000000010b086987 _TTRXFo___XFdCb___ + 39
9 Foundation 0x000000010b8572cd __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
10 Foundation 0x000000010b856faf -[NSBlockOperation main] + 101
11 Foundation 0x000000010b8556ac -[__NSOperationInternal _start:] + 672
12 Foundation 0x000000010b8515ef __NSOQSchedule_f + 201
13 libdispatch.dylib 0x00000001134100cd _dispatch_client_callout + 8
14 libdispatch.dylib 0x00000001133ede6b _dispatch_queue_serial_drain + 236
15 libdispatch.dylib 0x00000001133eeb9f _dispatch_queue_invoke + 1073
16 libdispatch.dylib 0x00000001133f13b7 _dispatch_root_queue_drain + 720
17 libdispatch.dylib 0x00000001133f108b _dispatch_worker_thread3 + 123
18 libsystem_pthread.dylib 0x00000001137bf746 _pthread_wqthread + 1299
19 libsystem_pthread.dylib 0x00000001137bf221 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
在过去,我也看到它因以下错误而崩溃: “尝试递归调用-save:on context offorted”。
任何想法是怎么回事?我将这些东西包装成NSOperation块的全部原因是为了防止这种情况。显然这不起作用。这是零星的,所以我不确定它是否已经解决了。
我猜测正在发生的事情是它仍然在删除数据的过程中,当它试图写入数据时。
答案 0 :(得分:1)
您没有正确执行Core Data并发。正确的方法是使用perform
上的performAndWait
和NSManagedObjectContext
方法。像代码一样使用操作队列中的上下文是与并发相关的错误的处方。
调度队列对您没有帮助。您可以仍然使用调度队列,但您还必须使用Core Data的并发方法来避免问题。