1

所以我知道NSManagedObjects这不是线程安全的,从后台线程获取对象的最佳方法是使用[context objectWithId:id];,因此传递对象 id 而不是实际对象。

假设我有一个全球性NSManagedObjectAppDelegate(不是最好的设计模式,但只是举例)NSManagedObject *myObject;

objectId从后台线程访问该对象是否安全?像这样:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        objectId = appDelegate.myObject.objectId;
        //is this thread safe?
}
4

2 回答 2

4

这是不安全的,因为不能保证调用objectIDmyObject安全的。您应该在块之外(例如在主线程上)访问 objectID,然后在块中使用它。就像是:

NSManagedObjectID *objectID = appDelegate.myObject.objectId;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // use objectID here.
}
于 2012-06-25T00:55:48.820 回答
1

您需要为您使用的每个线程(历史上)有一个单独的上下文。由于 dispatch_async 不能保证在任何给定线程上运行,因此您需要在块内创建上下文。或者,在 iOS 5.0 或更高版本上,NSManagedContext 带有新的并发模式。上下文将创建自己的私有串行队列,供您将块传递给。如果您需要支持 iOS 4.x,那么您可以模仿这种行为。创建一个串行队列,并且只访问该队列的上下文。

您可能不会做任何导致来自两个不同线程的查询或上下文更改的事情,因为它可能会创建竞争条件。

于 2012-06-25T01:08:39.130 回答