将对NSManagedObject属性的引用传递给后台线程

时间:2012-12-20 11:07:18

标签: ios core-data thread-safety nsmanagedobject nsmanagedobjectcontext

我想要做的是:

Product *product = [fetchResult lastObject];

NSString *productID = product.atProductID;

dispatch_async(queue, ^(void){
// Something with productID like
NSLog(@"productID is %@", productID);
});

这样做是否安全,或者我是否需要为辅助队列创建另一个上下文并通过其内部ID获取产品,然后处理其atProductID属性?

更新 嗯,它揭示了实际上是不安全的。一个简单的解决方案是制作productID字符串的副本:

Product *product = [fetchResult lastObject];

NSString *productID = [product.atProductID copy];

dispatch_async(queue, ^(void){
// Something with productID like
NSLog(@"productID is %@", productID);
});

这是安全的,因为您不在后台线程上保留对上下文或其派生的任何引用。这样做的原因是上下文缓存从持久性存储中获取的数据,并且它本身管理该缓存。无论你是否保留指向该缓存的指针,它都可以更改或销毁它,除非在上下文的线程中使用它。

2 个答案:

答案 0 :(得分:0)

您的代码看起来很好。如果要使用,您只需要一个单独的托管对象上下文 使用它做一些事情,例如长时间提取或更改托管对象。

此外,您可以毫无问题地使用async块范围内的变量。这是CGD的巨大优势。这些线程包含内存,所以我希望复制字符串。您可以通过记录指针地址来检查。

答案 1 :(得分:-1)

之前没有使用过dispatch_async,但这段代码看起来并不健康

您正在使用在一个线程中创建的变量并将其直接传递到另一个代码块。正确的方法是将对象/参数传递给方法。

有一点需要注意,你的问题不是100%准确。执行时

NSString *productID = product.atProductID;

您正在创建一个全新的NSString对象,该对象与NSManagedObject(即Product)无关。因此,您的问题是关于为dispatch_async传递参数而与NSManagedObjects没有多大关系