您可以通过以下两种方式之一访问上下文:
- 在其线程/队列上。 适用于受限上下文和主队列上下文。 您可以自由地从它们自己的线程中访问它们。
- 使用
-performBlock:
,如果它是私有队列上下文或者您正在从不属于它所属的线程中访问该上下文。
您不能使用dispatch_async
来访问上下文。 如果您想要异步执行操作,则需要使用-performBlock:
。
如果您以前正在使用单个上下文,并且使用dispatch_async
来访问它,那么您就违反了线程限制规则。
更新
当您调用[[NSManagedObjectContext alloc] init]
时,这与[[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]
在功能上相同。
NSManagedObjectContext
始终是线程限制的。
至于执行多个方法,您可以在同一个块中调用它们:
NSManagedObjectContext *moc = ...;
[moc performBlock:^{
}];
或者,如果您希望它们彼此全部异步化,则可以将它们嵌套:
NSManagedObjectContext *moc = ...;
[moc performBlock:^{
[moc performBlock:^{
}];
[moc performBlock:^{
}];
}];
因为-performBlock:
是可重入安全的,所以您可以随意嵌套它们。
更新异步保存
要进行异步保存,您应该拥有两个(或更多)上下文:
- 主队列上下文,用于UI交互
- 私有队列上下文,负责保存
私有上下文拥有一个NSPersistentStoreCoordinator
,而主队列上下文则将其作为父级。
所有工作都在主队列上下文中完成,您可以在主线程上安全地保存它。那次保存将是瞬时的。之后,您进行异步保存:
NSManagedObjectContext *privateMOC = ...;
NSManagedObjectContext *mainMOC = ...;
NSError *error = nil;
if (![mainMOC save:&error]) {
NSLog(@"Main MOC save failed: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
[privateMOC performBlock:^{
NSError *error = nil;
if (![privateMOC save:&error]) {
NSLog(@"Private moc failed to write to disk: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
}];
如果您已经有一个应用程序,您只需要做以下几步:
- 创建您的私有模型
- 将其设置为主要模型的父级
- 更改主要模型的初始化
- 每次在主要模型上调用保存时添加私有块保存方法
您可以从那里进行重构,但那就是您真正需要更改的所有内容。