我有一个旧项目(从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中的一个bug? 最佳答案
调用-[NSManagedObjectContext init]
只是带有参数-[NSManagedObjectContext initWithConcurrencyType:]
的NSConfinementConcurrencyType
的包装器。这将创建一个NSManagedObjectContext
的实例,该实例使用过时的线程限制模型-该模型不使用队列。使用传递值init
的initWithConcurrencyType:
或NSConfinementConcurrencyType
创建的上下文与队列方法performBlock:
或performBlockAndWait:
不兼容。
使用-[NSManagedObjectContext initWithConcurrencyType:]
创建上下文,并根据需要传递NSPrivateQueueConcurrencyType
或NSMainQueueConcurrencyType
。结果创建的上下文与performBlock:
和performBlockAndWait:
兼容,并将使用ios 5中引入的队列限制模型。
关于objective-c - NSManagedObjectContext和performBlock,在iOS 8上进行更改吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26846260/