核心数据随机崩溃,可能存在并发问题(Random crash with core data, possible concurrency issue)

编程入门 行业动态 更新时间:2024-10-24 06:38:35
核心数据随机崩溃,可能存在并发问题(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

在过去,我也看到它崩溃,出现以下错误:“尝试递归调用 - 保存:在上下文中中止”。

任何想法是怎么回事? 我将这些东西包装成NSOperation块的全部原因是为了防止这种情况。 显然这没有用。 这是零星的,所以我不确定它是否被解决了。

我猜测发生了什么事是它在试图写入数据时仍然在删除数据。

I have a section of code where it firstly empties out a Core Data table, then fills it back up with new and updated data. This code is inside a DispatchQueue.main.async block, that occurs after an asynchronous request has been completed. This is the relevant code from the function.

Here is my code:

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)

I have random crashes from time to time on the addOperation block of code for some reason. In the most recent crash, an exception breakpoint has been trigger on:

try self.managedObjectContext.save()

If I hit continue, it lands on this breakpoint again, then when I hit continue again, it crashes showing assembly and this error:

*** 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

In the past, I've also seen it crash with the following error: "attempt to recursively call -save: on the context aborted".

Any ideas what is going on? The whole reason I wrapped these things into NSOperation blocks was in an attempt to prevent this. Clearly that didn't work. This is sporadic, so I'm never sure if its been solved or not.

I'm guessing what is happening is that its still in the process of deleting data, when it tries to write data.

最满意答案

你没有正确地进行核心数据并发。 正确的方法是在NSManagedObjectContext上使用perform和performAndWait方法。 在您的代码中使用操作队列中的上下文会导致并发相关的错误。

派遣队列在这里没有帮助。 您仍然可以使用调度队列,但您还必须使用Core Data的并发方法来避免问题。

You're not doing Core Data concurrency correctly. The right way is to use the perform and performAndWait methods on NSManagedObjectContext. Using a context in an operation queue like your code does is a recipe for concurrency related bugs.

Dispatch queues don't help you here. You can still use dispatch queues, but you must also use Core Data's concurrency methods to avoid problems.

更多推荐

本文发布于:2023-08-07 19:15:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1465960.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:核心   数据   Random   crash   issue

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!