NSManagedObjectContext 和 performBlock,iOS 8 上的变化?
Posted
技术标签:
【中文标题】NSManagedObjectContext 和 performBlock,iOS 8 上的变化?【英文标题】:NSManagedObjectContext and performBlock, changes on iOS 8? 【发布时间】:2014-11-10 14:41:22 【问题描述】:我有一个使用这个简单代码的旧项目(从 ios 7 开始):
在 AppDelegate 中我创建了 managedObjectContext:
- (NSManagedObjectContext *)managedObjectContext
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil)
return _managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator)
return nil;
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
然后,我在视图控制器中执行更新操作:
[context performBlock:^
[context deleteObject:anObject];
NSError *error = nil;
if (![context save:&error])
NSLog(@"Error saving context");
];
我确定这段代码在 iOS 7.0 上可以正常运行,但在 iOS 8 上的 performBlock:
调用中崩溃并出现以下错误:
只能在使用队列创建的 NSManagedObjectContext 上使用 -performBlockAndWait:。
我可以像这样解决更改 NSManagedObjectContext 实例的 init 方法的错误:
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
但我不明白为什么这种行为会改变。在 NSManagedObjectContext 的文档中,您可以阅读:
这样做的结果是上下文假定默认所有者是分配它的线程或队列——这由调用其 init 方法的线程确定。
因此,在我的第一个示例中,使用简单的init
调用,上下文的队列所有者是主线程。
performBlock:
调用也是在主线程上进行的,所以我不明白为什么会出现这个错误。是我遗漏了什么还是 iOS 8 中的错误?
【问题讨论】:
【参考方案1】:调用-[NSManagedObjectContext init]
只是-[NSManagedObjectContext initWithConcurrencyType:]
的包装器,带有参数NSConfinementConcurrencyType
。这会创建一个 NSManagedObjectContext
的实例,它使用过时的线程限制模型 - 不 使用队列。使用 init
或 initWithConcurrencyType:
创建并传递值 NSConfinementConcurrencyType
的上下文与队列方法 performBlock:
或 performBlockAndWait:
不兼容。
使用-[NSManagedObjectContext initWithConcurrencyType:]
创建您的上下文,并根据需要传递NSPrivateQueueConcurrencyType
或NSMainQueueConcurrencyType
。结果创建的上下文与performBlock:
和performBlockAndWait:
兼容,并将使用iOS 5 中引入的队列限制模型。
【讨论】:
谢谢。我认为我从 Apple Docs 中引用的那句话具有误导性:-)以上是关于NSManagedObjectContext 和 performBlock,iOS 8 上的变化?的主要内容,如果未能解决你的问题,请参考以下文章
NSManagedObjectContext 和 performBlock,iOS 8 上的变化?
CoreData 和 NSManagedObjectContext
应用退出和重新启动时不保存 NSManagedObjectContext