多个NSManagedObjectContexts或单个上下文和-performBlock

时间:2014-03-20 16:17:19

标签: ios objective-c core-data

我一直在使用单个NSManagedObjectContext的核心数据,所有提取,保存,后台更新操作都将通过帮助程序类在单个上下文中完成,我计划实现多个{{1方法(在我的大部分搜索中,这是推荐的解决方案)。

我的问题是:NSManagedObjectContext是唯一一个为该上下文执行代码的人吗?我们不能做类似下面的事情:

performBlock

(即)执行除- (void) checkSyncServer { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ //do something here, check and fetch data // create NSManagedObject's [_tempContext save:&error]; //masterContext will merge changes through notification observers }); } 方法之外的代码。如何执行多个异步方法并执行保存?

但是,我发现单个上下文(由一个单例-performBlock类管理)更易于使用。

这个带有NSObject的多重上下文看起来更复杂(就执行流程而言)。有更好的解决方案吗?

1 个答案:

答案 0 :(得分:19)

您可以通过以下两种方式之一访问上下文:

  • 在其线程/队列上。这适用于受限上下文和主队列上下文。您可以从他们自己的主题中自由访问它们。
  • 使用-performBlock:,如果它是私有队列上下文,或者您正在从其所属的线程以外的线程触摸上下文。

您无法使用dispatch_async来访问上下文。如果您希望操作是异步的,则需要使用-performBlock:

如果您之前使用的是单个上下文并且使用dispatch_async进行了触摸,那么您违反了线程限制规则。

更新

当您致电[[NSManagedObjectContext alloc] init]时功能上等同于[[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]

NSManagedObjectContext 总是受到线程限制。

至于执行多个方法,您可以在同一个块中全部调用它们:

NSManagedObjectContext *moc = ...;
[moc performBlock:^{
  //Fetch something
  //Process data
  //Save
}];

如果你想让它们彼此异步,你可以嵌套它们:

NSManagedObjectContext *moc = ...;
[moc performBlock:^{
  //Fetch Something
  [moc performBlock:^{
    //Process Data
  }];
  [moc performBlock:^{
    //Save
  }];
}];

由于-performBlock:可以重新进入,因此您可以随意嵌套它们。

更新异步保存

要进行异步保存,您应该有两个上下文(或更多):

  • UI与之对话的主要队列上下文
  • 保存的专用队列上下文

私有上下文有NSPersistentStoreCoordinator,主队列上下文将私有作为其父。

所有工作都在主队列上下文中完成,您可以安全地保存它,通常是在主线程上。这种保存将是即时的。然后,您执行异步保存:

NSManagedObjectContext *privateMOC = ...;
NSManagedObjectContext *mainMOC = ...;

//Do something on the 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();
  }
}];

如果您已有应用,那么您需要做的就是:

  • 创建您的私人moc
  • 将其设为主
  • 的父级
  • 更改主要的init
  • 每当您在主
  • 上调用save时,添加私有块保存方法

你可以从那里进行重构,但这就是你 需要改变的所有内容。