【问题标题】:Core Data: mutex/deadlock when changing two objects in different threads?核心数据:在不同线程中更改两个对象时的互斥锁/死锁?
【发布时间】:2011-11-14 20:40:57
【问题描述】:

我有两个核心数据对象:一个组织和一个人,它们链接在一起。

如果我在不同的线程中更改它们并同时保存它们会有问题吗?所以线程是并行运行的:

线程 1: - 使用 NSManagedObjectID 加载组织 - 对对象进行更改 - 保存对象

线程 2: - 使用 NSManagedObjectID 加载 Person - 对对象进行更改 - 保存对象

对我来说,我似乎因此得到了一个互斥锁;不是每次,但有时会发生。如果这是问题 - 解决方案是什么? :)

非常感谢!

斯蒂芬

【问题讨论】:

    标签: objective-c core-data mutex deadlock


    【解决方案1】:

    是的,如果您使用相同的 NSManagedObjectContext,这将是一个问题。 Core-Data,不是完全线程安全的,NSManagedObjectID 是。在您的后台线程上,您必须使用相同的存储创建一个单独的上下文,然后保存,它会在保存时通知主线程以合并两个上下文。您可以通过创建合并策略来控制此合并。所以你仍然可以做到,但并不像希望的那么容易。

    【讨论】:

    • 我确实有单独的 NSManagedObjectContexts 并且只有一个 PersistentStore。所以我认为它应该可以工作,不是吗?
    • 如何合并结果?你设置通知了吗?
    • 是的,通知已设置。更改与“ [mainContext performSelectorOnMainThread:mergeChanges withObject:notification waitUntilDone:YES];”合并。
    • 是对象创建还是修改的问题?在单独的线程上创建对象时,不能保证该对已经创建。您使用的是 NSOperations 还是直线程?
    【解决方案2】:

    不要让线程并行运行。 CoreData 非常高效。只需在同一个线程中按顺序进行数据操作并保存一次。

    Core Data 的设计方式很少需要拥有多个NSManagedObjectContext。一个这样的上下文应始终在给定时间在一个线程上运行。

    编辑

    如果由于您依赖网络服务等而无法做到这一点,请考虑使用NSNotifications 并仅在主线程上进行保存。 (与performSelectorOnMainThread)。

    【讨论】:

    • 不幸的是,这并不容易。在后台运行异步网络呼叫 - 有时我会得到一个组织:存储它。有时我会得到一个客户 - 存储它。
    • 在答案中查看我的补充。
    • 但是如何让 NSManagedObject 进入主线程呢?如果我在后台填充对象,我不能将它传递给另一个线程,可以吗?
    • 你没有得到 NSManagedObject 到主线程,它已经在那里了。您只需要(从您的网络线程)关于这个新对象到主线程(例如通过通知)获取信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 2011-07-24
    相关资源
    最近更新 更多