gpt4 book ai didi

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

转载 作者:技术小花猫 更新时间:2023-10-29 10:45:21 30 4
gpt4 key购买 nike

长期以来,我一直在将 Core Data 与单个 NSManagedObjectContext 结合使用,所有获取、保存、后台更新操作都将通过辅助类在单个上下文中完成,我计划实现多个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 类管理)更易于使用。

这种具有ContextConcurrencyType 的多重上下文看起来更复杂(在执行流程方面)。有更好的解决方案吗?

最佳答案

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

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

您不能使用 dispatch_async 访问上下文。如果您希望操作是异步的,那么您需要使用 -performBlock:

如果您之前使用的是单个上下文,并且您正在使用 dispatch_async 访问它,那么您就违反了线程限制规则。

更新

当你调用 [[NSManagedObjectContext alloc] init] 时,它在功能上等同于 [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]

NSManagedObjectContext 始终 是线程限制的。

至于执行多个方法,你可以在同一个 block 中调用它们:

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

或者如果您希望它们彼此异步,您可以嵌套它们:

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

由于 -performBlock: 是可重入安全的,您可以随意嵌套它们。

更新异步保存

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

  • UI 与之对话的主队列上下文
  • 保存的私有(private)队列上下文

私有(private)上下文有一个NSPersistentStoreCoordinator,主队列上下文有私有(private)作为它的父级。

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

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();
}
}];

如果您已经有一个应用程序,您需要做的就是:

  • 创建您的私有(private) moc
  • 将其设置为您的主节点的父节点
  • 更改主程序的初始化
  • 每当您在 main 上调用 save 时添加私有(private) block 保存方法

您可以从那里进行重构,但这就是您真正需要更改的全部内容。

关于ios - 多个 NSManagedObjectContexts 或单个上下文和 -performBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22538981/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com