重置存储时核心数据崩溃:'无法从此NSManagedObjectContext的协调器'

时间:2016-11-14 14:33:16

标签: ios swift core-data nsmanagedobject nsmanagedobjectcontext

我试图在我用Swift编写的iOS应用程序中删除Core数据的持久存储时遇到崩溃。流程是直截了当的:当我从应用程序注销时,我删除了商店:

destroyPersistentStoreAtURL

我在应用程序中使用本机Core Data实现,并且使用performBlock / performBlockAndWait对托管对象进行每次访问。此外,这些操作位于NSOperationQueue。流程如下:

  1. 退出
  2. cancelAllOperations& waitUntilAllOperationsAreFinished已实施的队列上的performBlocks
  3. maxConcurrentOperationCount = 1performBlocks
  4. 的队列中
  5. 最后,我添加了一个破坏前一个NSOperationQueue
  6. 中持久存储的操作

    有时,我遇到了崩溃,我无法理解为什么。从我看到的,它是与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

    非常感谢任何帮助!

4 个答案:

答案 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)

@汤姆

是的,你是对的。所以我给你发了一个例子:

&#13;
&#13;
let queue = NSOperationQueue

queue.addOperationWithBlock{
  let moc = newPrivateQueueManagedObjectContext()
  moc.performBlock {
    //some work to do on the context
}
&#13;
&#13;
&#13;

然后有时我销毁了商店,但在此之前我取消了上述队列的操作。不过,有时候我会看到一次崩溃......