【问题标题】:Is it necessary to do Core Data reads within performBlock when using NSMainQueueConcurrencyType?使用 NSMainQueueConcurrencyType 时是否需要在 performBlock 中读取核心数据?
【发布时间】:2012-04-17 07:42:17
【问题描述】:

根据 Daniel Eggert 在 this question 中的回答,当使用带有 NSPrivateQueueConcurrencyType 的托管对象上下文时,有必要在 performBlock: 或 @ 中执行任何接触它或属于它的对象的任何事情 987654325@

NSMainQueueConcurrencyType 也一样吗?想象以下代码在主线程上运行,例如在 UIViewController 中:

self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
//moc setup

__block RHWidget *widget = nil;

[self.moc performBlockAndWait:^{
    widget = [(RHWidget *)[self.moc objectWithID:self.widgetObjectID] retain];
}];

self.labelView.text = widget.descriptionString;

[widget release];

既然我们知道我们在主线程上,那么在块外使用小部件是否安全?或者有必要这样做:

__block NSString *description = nil;

[self.moc performBlockAndWait:^{
    RHWidget *widget = (RHWidget *)[self.moc objectWithID:self.widgetObjectID];
    description = [widget.descriptionString copy];
}];

self.labelView.text = description;

[description release];

如果有另一个NSManagedObjectContext,可能是私有队列类型,分块工作并将更改作为parentContext推送到self.moc,事情会改变吗?

当然,这是一个稍微做作的示例,但最好安全地将小部件传递给需要访问小部件某些属性的模态视图控制器。我是否应该传递小部件的 objectID 并在新视图控制器的 performBlock: 中重新获取它?

【问题讨论】:

  • 有一篇非常全面的文章here 描述了包括上下文并发类型和嵌套上下文在内的各种方法。

标签: ios core-data concurrency


【解决方案1】:

更新: 根据WWDC 2011 Session 303 (What's New in Core Data on iOS)NSMainQueueConcurrencyType 旨在允许在主线程上进行正常消息传递;您只需要在与来自不同线程的上下文交互时使用-performBlock:。 (下面我原始答案的相关部分。)


我制作了一个或两个应用程序,它修改了 Xcode 的默认“Master-Detail”应用程序模板,以使“main”MOC(由应用程序委托创建并在视图控制器之间传递)仅主队列,并且父我用于后台操作的私有队列上下文,例如从 Web 获取中导入数据。因此,上下文及其对象的大多数使用都没有被包裹在performBlock: 中。 (我唯一一次使用 performBlock: 是将更改从后台任务上下文推送回主上下文以更新 UI。)工作得很好。

【讨论】:

  • 这或多或少是我正在做的;我有一个带有NSOperationQueue 的单例和带有NSPrivateQueueConcurrencyType 的上下文,它们被传递给每个操作。这些操作获取对象,完成它们的工作,保存本地上下文,然后保存父上下文,所有这些都在performBlock: 中。一切似乎都正常,但我担心意外的竞争条件或内存管理问题。
  • @roland。我不认为这是一种安全的方法,因为 NSOperationQueue 可以使用多个线程(即使它的 maxConcurrentOperationCount 为 1)。当您使用父/子上下文机制时,并发问题会更少,因为访问存储的始终是父上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 2014-03-05
  • 2017-10-31
  • 2015-04-30
  • 1970-01-01
  • 2019-10-24
相关资源
最近更新 更多