【问题标题】:Can you use an NSManagedObject outside of it's context's performBlock?你可以在上下文的 performBlock 之外使用 NSManagedObject 吗?
【发布时间】:2013-05-20 02:18:00
【问题描述】:

NSManagedObjectContext 已经添加了 performBlock: 和 performBlockAndWait: 方法来帮助简化并发。我一直在使用它们——可能相当天真——我才意识到有一个我从未真正问过的问题。

如果我在其中一个 performBlock 方法中创建一个 NSManagedObject 子类,它的“主”线程就是它的父上下文的线程——在 NSPrivateQueueConcurrencyType 的情况下,它可能是一个我没有其他访问权限的独立线程。

那么我是否需要调用 performBlock 来访问托管对象中包含的数据?或者在使用吸气剂的情况下,是否有一种背景魔法可以帮助保护我? (或者二传手,虽然这似乎是个坏主意……)

【问题讨论】:

    标签: ios objective-c core-data


    【解决方案1】:

    NSManagedObject 不应该在其managedObjectContexts 线程/队列之外使用(有时它可以工作,有时你会崩溃 ==> 不要这样做)。

    CoreData 不保证对对象的安全读取访问。

    要访问“私有队列”上下文所拥有的对象,请始终使用[context performBlock:...][context performBlockAndWait:...],除非您访问其objectIDmanagedObjectContext 属性。

    【讨论】:

    • 谢谢,几乎我认为是必要的......我希望我错了。我需要重新观看他们介绍该技术的 WWDC 视频,因为我不记得他们必须这样做......再说一次,我怀疑我需要重新观看很多 WWDC 视频。
    • 我想补充一点,Apple 工程师明确声明NSManagedObject 上的读取不是线程安全的,因为核心数据会缓存,而缓存写入不是线程安全的
    【解决方案2】:

    您确实需要使用performBlock:performBlockAndWait:,但有一个例外。如果您使用的是NSMainQueueConcurrencyType并且您正在使用主队列上的托管对象,您可以直接访问它,没有阻塞。当您需要从托管对象更新 UI 时,这会非常方便,反之亦然。

    【讨论】:

    • 另一个例外是NSConfinementConcurrencyType,它类似于主队列,只是针对特定线程(托管上下文的“旧”版本)
    • 我想我应该更好地表达我的问题,因为它基本上只与 NSPrivateQueue 和 NSMainQueue 类型有关......即使那样,由于这个奇妙的例外,主要是私有队列版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2013-09-25
    • 2019-11-08
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多