【发布时间】:2016-09-24 17:47:00
【问题描述】:
我突然被以 managedObjectContexts 形式出现的核心数据问题所困扰,三分之二的时间为零:发病或多或少与升级到 Xcode 8 相吻合。新的 NSPersistentContainer 类似乎提供了一个解决问题的机会我的问题并摆脱一些丑陋的代码。不幸的是,我无法让它工作。
在 AppDelegate.h 中
@property (readonly, strong, nonatomic) NSPersistentContainer *persistentContainer;
在 AppDelegate.m 中:
@synthesize persistentContainer = _persistentContainer;
- (NSPersistentContainer *)persistentContainer
{
if (!_persistentContainer) {
_persistentContainer = [NSPersistentContainer persistentContainerWithName:@"I_WILL_PERSIST"];
__block BOOL storesWereLoaded = NO;
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *psd, NSError *error) {
if (error) {
NSLog(@"loadPersistentStoresWithCompletionHandler: persistent container could not load store %@. Error: %@",
psd, error.debugDescription);
} else {
storesWereLoaded = YES;
}
}];
if (storesWereLoaded) {
NSLog(@"Stores were loaded");
} else {
NSLog(@"Stores were not loaded");
}
}
return _persistentContainer;
}
该应用程序是一个小型测试应用程序,其中一个 arrayController 绑定(在 IB 中)到 App Delegate.persistentContainer.viewContext。 App Delegate 已连接且不为零。 persistentContainer getter 被重复调用,但块内的 NSLog 永远不会触发,控制台显示:
在没有托管对象上下文的情况下无法执行操作 2016-09-24 19:34:39.207 I_WILL_PERSIST[5588:180829] (0 CoreFoundation
0x00007fff8da994f2 __exceptionPreprocess + 178 1 libobjc.A.dylib
0x00007fff8ed6173c objc_exception_throw + 48 2 核心基础
0x00007fff8db004bd +[NSException raise:format:] + 205 3 AppKit
0x00007fff85d411c4 -[_NSManagedProxy _managedObjectContext] + 66
问题出在我不稳定的块编程技巧上吗?是签名/权限问题(应用程序不是沙盒,代码签名自动)? Core Data 怎么了?
====编辑==== 升级到 Mac OS 10.12 (Sierra) 后,NSPersistentContainer 失败并出现错误:
2016-09-28 20:55:53.256588 osPersist[1936:41151] [error] error:
-addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/user/Library/Application%20Support/osPersist/osPersist.sqlite options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2} with userInfo dictionary {
reason = "Failed to create file; code = 2"; } 2016-09-28 20:55:53.256747 osPersist[1936:41151] Unresolved error Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2}, {
reason = "Failed to create file; code = 2"; }
数据库创建失败的原因尚不清楚:无论是否使用代码签名都会发生这种情况。我已经提交了错误报告并提出了支持请求。
【问题讨论】:
-
我看到了一些错误,但我认为没有一个错误会导致该错误。 1) 您在调用异步块后立即测试
storesWereLoaded。 2)如果加载失败,你不释放协调器,这意味着它会存在,但未初始化,下一次通过。这将导致if语句被跳过。 -
感谢您的反馈,但是是什么让您认为 loadPersistentStoresWithCompletionHandler: 是一个异步块?从技术上讲,您是正确的,即使 loadPersistentStoresWithCompletionHandler:, _persistentContainer 仍然可以被初始化。碰巧,persistentContainerWithName: 已经返回 nil,所以实际上 loadPersistentStoresWithCompletionHandler: 被调用了两次(通过绑定)。我什至不确定 loadPersistentStoresWithCompletionHandler: 是否必要——标题中的 cmets 表明它不是。
-
我不知道有一个 Apple API 需要一个完成块来进行同步调用。
-
对。无论如何,我做了一些研究,据我所知,完成处理程序相当于委托调用或通知。因此, loadPersistentStores 在辅助线程上执行任何操作,并且在完成后,调用该块并在主线程上执行。除了,在我的情况下,它永远不会被调用......因为 persistentContainerWithName: 返回 nil 并且 persistentContainerWithName: 不会对 nil 对象执行任何操作。
-
希望您使用的是 iOS 10 模拟器?当我在带有 Xcode 8 的 iOS 9 模拟器上运行时,我遇到了同样的问题。
标签: objective-c macos nsmanagedobjectcontext xcode8