[英]Random crash with core data, possible concurrency issue
我有一段代碼,它首先清空核心數據表,然后用新的和更新的數據填充它。 這段代碼位於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:”。
有什么想法嗎? 我將這些內容包裝到NSOperation塊中的全部原因是為了防止這種情況。 顯然這沒有用。 這是零星的,所以我不確定它是否已解決。
我猜發生了什么事,當它試圖寫入數據時,它仍在刪除數據的過程中。
您沒有正確執行Core Data並發。 正確的方法是在NSManagedObjectContext
上使用perform
和performAndWait
方法。 像代碼一樣在操作隊列中使用上下文是解決與並發相關的錯誤的訣竅。
派遣隊列對您沒有幫助。 您仍然可以使用調度隊列,但是還必須使用Core Data的並發方法來避免問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.