我试图在我用Swift编写的iOS应用程序中删除Core数据的持久存储时遇到崩溃。流程是直截了当的:当我从应用程序注销时,我删除了商店:
destroyPersistentStoreAtURL
我在应用程序中使用本机Core Data实现,并且使用performBlock
/ performBlockAndWait
对托管对象进行每次访问。此外,这些操作位于NSOperationQueue
。流程如下:
cancelAllOperations
& waitUntilAllOperationsAreFinished
已实施的队列上的performBlocks
maxConcurrentOperationCount = 1
在performBlocks
NSOperationQueue
有时,我遇到了崩溃,我无法理解为什么。从我看到的,它是与managedObjectsIDs和retain相关的东西。看看:
2016-11-14 15:51:58.053 ******[3912:179074] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** First throw call stack:
(
0 CoreFoundation 0x000000010ca0f34b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010c05321e objc_exception_throw + 48
2 CoreData 0x000000010c5683b2 _PFRetainedObjectIDCore + 1074
3 CoreData 0x000000010c5507fc -[NSManagedObjectContext objectWithID:] + 668
4 CoreData 0x000000010c590264 _faultBatchAtIndex + 1524
5 CoreData 0x000000010c59217a -[_PFBatchFaultingArray retainedObjectAtIndex:] + 74
6 CoreData 0x000000010c592262 -[_PFBatchFaultingArray objectAtIndex:] + 50
7 CoreData 0x000000010c67d9de __72-[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:]_block_invoke + 190
8 CoreData 0x000000010c55adc7 developerSubmittedBlockToNSManagedObjectContextPerform + 199
9 CoreData 0x000000010c55ac7f -[NSManagedObjectContext performBlockAndWait:] + 255
10 CoreData 0x000000010c67d3b6 -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:] + 694
11 CoreData 0x000000010c681d75 __82-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:]_block_invoke + 1077
12 CoreData 0x000000010c55adc7 developerSubmittedBlockToNSManagedObjectContextPerform + 199
13 CoreData 0x000000010c55ac7f -[NSManagedObjectContext performBlockAndWait:] + 255
14 CoreData 0x000000010c681927 -[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:] + 119
15 CoreFoundation 0x000000010c9ad19c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
16 CoreFoundation 0x000000010c9ad09b _CFXRegistrationPost + 427
17 CoreFoundation 0x000000010c9ace02 ___CFXNotificationPost_block_invoke + 50
18 CoreFoundation 0x000000010c96fea2 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 2018
19 CoreFoundation 0x000000010c96ef3b _CFXNotificationPost + 667
20 Foundation 0x000000010bb1b0ab -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
21 CoreData 0x000000010c5432b0 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 704
22 CoreData 0x000000010c562b50 -[NSManagedObjectContext(_NSInternalNotificationHandling) _processChangedStoreConfigurationNotification:] + 2976
23 CoreData 0x000000010c5d97ed __95-[NSManagedObjectContext(_NSInternalNotificationHandling) _sendOrEnqueueNotification:selector:]_block_invoke + 109
24 CoreData 0x000000010c55adc7 developerSubmittedBlockToNSManagedObjectContextPerform + 199
25 libdispatch.dylib 0x000000010e0250cd _dispatch_client_callout + 8
26 libdispatch.dylib 0x000000010e0058d6 _dispatch_main_queue_callback_4CF + 406
27 CoreFoundation 0x000000010c9d34f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
28 CoreFoundation 0x000000010c998f8d __CFRunLoopRun + 2205
29 CoreFoundation 0x000000010c998494 CFRunLoopRunSpecific + 420
30 GraphicsServices 0x000000010f5d0a6f GSEventRunModal + 161
31 UIKit 0x000000010a050964 UIApplicationMain + 159
32 ****** 0x000000010817e932 main + 114
33 libdyld.dylib 0x000000010e07168d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
非常感谢任何帮助!
答案 0 :(得分:5)
您需要重置此操作之前使用的managedObjectContext
。
致电managedObjectContext.reset()
答案 1 :(得分:1)
错误告诉您,在销毁了从中获取它的持久存储后,您仍然在尝试使用托管对象。这确保导致这次崩溃。
无法准确说明发生这种情况的方法,但如果您在删除商店后保留对管理对象的任何引用,那么您将获得此信息。使用performBlock
等取消操作不会产生任何影响,如果最后您还在尝试使用不再拥有持久存储的托管对象。< / p>
答案 2 :(得分:1)
我遇到了同样的问题,Tom提示假设脏对象 - 以前住在旧商店 - 在我从协调器中删除持久存储之后仍然是托管对象上下文的一部分。在我的情况下,我实现了一个&#34;恢复到上次保存的文档版本&#34;这需要确保首先丢弃这些脏对象。
[_managedObjectContext reset]
[_managedObjectContext.persistentStoreCoordinator removePersistentStore:_store error:outError]
如果您的代码中仍然引用了这些对象,object.managedObjectContext
将为零 - 这是一个很好的恢复提示。
答案 3 :(得分:0)
@汤姆
是的,你是对的。所以我给你发了一个例子:
let queue = NSOperationQueue
queue.addOperationWithBlock{
let moc = newPrivateQueueManagedObjectContext()
moc.performBlock {
//some work to do on the context
}
&#13;
然后有时我销毁了商店,但在此之前我取消了上述队列的操作。不过,有时候我会看到一次崩溃......