自从升级到 XCode 6.3 和 iOS 8.3 后,在将 NSManagedObjectContexts (MOC) 从后台合并到主线程 MOC 时,我的应用程序中出现了一个新错误。
我的架构在主线程上有一个主 MOC,并在其他线程上创建了几个后台 MOC,它们是临时的,仅用于同步新的服务器数据。当这些后台 MOC 保存时,我在主线程上监听通知NSManagedObjectContextDidSaveNotification并在主 MOC 上调用mergeChangesFromContextDidSaveNotification。
这是根据关于使用 Core Data 进行线程化的文档(请参阅Core Data Concurrency)。
这曾经可以正常工作,但是从这个更新开始,这个错误开始崩溃,我无法追溯到我的代码的特定行:
illegally invoked -perform* on dying NSManagedObjectContext at:
(
0 CoreData 0x28a2f273 <redacted> + 118
1 CoreData 0x28a32f09 <redacted> + 192
2 CoreFoundation 0x28c64e09 <redacted> + 12
3 CoreFoundation 0x28bbf515 _CFXNotificationPost + 1784
4 Foundation 0x29920749 <redacted> + 72
5 Foundation 0x2992522f <redacted> + 30
6 Foundation 0x29986a93 <redacted> + 98
7 Foundation 0x299867f7 <redacted> + 82
8 Foundation 0x299dfbd5 <redacted> + 408
9 CoreFoundation 0x28c72fed <redacted> + 20
10 CoreFoundation 0x28c706ab <redacted> + 278
11 CoreFoundation 0x28c709ff <redacted> + 734
12 CoreFoundation 0x28bbd201 CFRunLoopRunSpecific + 476
13 CoreFoundation 0x28bbd013 CFRunLoopRunInMode + 106
14 GraphicsServices 0x30359201 GSEventRunModal + 136
15 UIKit 0x2c361a59 UIApplicationMain + 1440
16 MyAppName 0x000c95a7 main + 170
17 libdyld.dylib 0x376c1aaf <redacted> + 2
)
我在 XCode 中打开了僵尸,寻找释放的上下文,但没有找到。调用合并的主线程侦听器如下所示:
- (void)coreDataDidSaveNotification:(NSNotification *)notification {
NSManagedObjectContext *savedContext = (NSManagedObjectContext *)notification.object;
if (savedContext != self.mainManagedObjectContext) {
__weak typeof(self) weakSelf = self;
[self.dispatch dispatchOnMainThread:^{
NSLog(@"before merge");
[weakSelf.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
NSLog(@"after merge");
}];
}
}
在崩溃发生之前调用“合并后”的日志消息,这更加令人困惑。我已经在通知的背景上下文中检查了 retainCount 并且在调用合并时它总是大于零,所以它不会在那个时候被释放。
知道发生了什么吗?