所以我知道NSManagedObjects
不是线程安全的,从后台线程获取对象的最好方法是使用[context objectWithId:id];
,因此传递对象id而不是实际对象。
假设我的NSManagedObject
中有一个全局AppDelegate
(不是最好的设计模式,只是举例)NSManagedObject *myObject;
从后台线程访问此对象的objectId
是否安全?像这样:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
objectId = appDelegate.myObject.objectId;
//is this thread safe?
}
答案 0 :(得分:3)
这不安全,因为无法保证在objectID
上调用myObject
是安全的。您应该访问块外部的objectID(例如,在主线程上),然后在块中使用它。类似的东西:
NSManagedObjectID *objectID = appDelegate.myObject.objectId;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// use objectID here.
}
答案 1 :(得分:1)
您需要为您使用的每个线程(历史上)设置单独的上下文。由于无法保证dispatch_async在任何给定线程上运行,因此您需要在块内创建上下文。或者,在iOS 5.0或更高版本上,NSManagedContext带有新的并发模式。上下文将创建自己的专用串行队列,以便将块传递给。如果您需要支持iOS 4.x,那么您可以在此行为后建模。创建一个串行队列,只访问该队列中的上下文。
您可能无法执行任何导致查询或从两个不同线程更改上下文的操作,因为它可能会创建竞争条件。