核心数据在 mergeChangesFromContextDidSaveNotification 期间崩溃

Core Data crash during mergeChangesFromContextDidSaveNotification

我在 Core Data private/internal 方法中随机发生了一次罕见的崩溃。

我的设置:

这一切都在 iOS 9.3 上。 这是在主线程上运行的代码(来自我的库 RTCoreDataStack):

[self.mainManagedObjectContext performBlock:^{
    [self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}];

我在崩溃报告中得到 EXC_BAD_ACCESS 和各种代码(模拟器上的 EXC_I386_GPFLT 或设备上的 SIGSEGV)。这是一个例子:

Thread 0 Crashed:
0   libobjc.A.dylib                      0x0000000180eedb90 objc_msgSend + 16
1   CoreData                             0x0000000183773010 -[NSManagedObjectContext _mergeRefreshObject:mergeChanges:withPersistentSnapshot:] + 132
2   CoreData                             0x00000001837745fc -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 2276
3   CoreData                             0x000000018377cd04 __90+[NSManagedObjectContext(_NSCoreDataSPI) _mergeChangesFromRemoteContextSave:intoContexts:]_block_invoke1353 + 68
4   CoreData                             0x000000018377508c developerSubmittedBlockToNSManagedObjectContextPerform + 192
5   CoreData                             0x0000000183774f54 -[NSManagedObjectContext performBlockAndWait:] + 216
6   CoreData                             0x000000018377c698 +[NSManagedObjectContext(_NSCoreDataSPI) _mergeChangesFromRemoteContextSave:intoContexts:] + 3420
7   CoreData                             0x0000000183774bb0 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 384
8   RTCoreDataStack                      0x00000001005e8d34 __43-[RTCoreDataManager handleMOCNotification:]_block_invoke (RTCoreDataManager.m:294)
9   CoreData                             0x000000018377508c developerSubmittedBlockToNSManagedObjectContextPerform + 192
10  libdispatch.dylib                    0x00000001812c147c _dispatch_client_callout + 12
11  libdispatch.dylib                    0x00000001812c6b84 _dispatch_main_queue_callback_4CF + 1840
12  CoreFoundation                       0x000000018182cd50 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
13  CoreFoundation                       0x000000018182abb8 __CFRunLoopRun + 1624
14  CoreFoundation                       0x0000000181754c50 CFRunLoopRunSpecific + 380
15  GraphicsServices                     0x000000018303c088 GSEventRunModal + 176
16  UIKit                                0x0000000186a3e088 UIApplicationMain + 200
17  MyApp                         0x0000000100131910 main (main.m:14)
18  ???                                  0x00000001812f28b8 0x0 + 0

好心人告诉我,当您使用 KVO 监控 NSMO 的 属性 时,可能会发生此类崩溃。

起初我尝试用Facebook的KVOController替换我自己的KVO代码,但没有帮助。然后我完全删除了 KVO 并且崩溃消失了。

因此,第一个结论是 当在 DidSaveNotification.

上发生合并期间从存储中删除的对象上设置 KVO 时,会发生崩溃。

此外,对于我的情况 - 不仅仅是 KVO 本身,还有我 KVO 编辑的对象被添加到 NSSet 的事实,该 NSSet 被设置为 property(assign)。我目前正在测试 KVO + strong 参考。