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

Posted

技术标签:

【中文标题】将对 NSManagedObject 的属性的引用传递给后台线程【英文标题】:Passing reference to NSManagedObject's attribute to a background thread 【发布时间】:2012-12-20 11:07:18 【问题描述】:

我想要做的是:

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);
);

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

【问题讨论】:

【参考方案1】:

您的代码看起来不错。如果您打算这样做,您只需要一个单独的托管对象上下文 用它做一些事情,例如长提取或更改托管对象。

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

【讨论】:

不,我检查过了:GCD 不会复制块内使用的变量,它只是保留一个指向它们的强指针,以确保在块完成执行之前它们不会被释放。 好的,欢迎来到 SOF。您需要勾选上面的复选标记。 ;-)【参考方案2】:

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

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

需要注意的是,您的问题并非 100% 准确。执行时

NSString *productID = product.atProductID;

您正在创建一个全新的 NSString 对象,它与您的 NSManagedObject(即产品)没有关联。因此,您的问题是关于为 dispatch_async 传递参数,与 NSManagedObjects 没有太大关系

【讨论】:

好吧,你没去,但你回答了我的问题。 :) 问题是当我访问与 NSManagedObject 属性相关的属性时,它是否真的创建了一个新的 NSString 实例,或者它只提供了对它的引用,因为它是 Cocoa 中的常见行为。如果可以,请提供一个链接,说明 NSManagedObject 属性访问器执行复制。 很高兴我做到了:) 为了将来参考,您可以通过将产品 ID 分配给其他东西(在 NSString 初始化之后)并记录两个变量(NSString 对象和属性)来查看它们是否有相同或不同的值 无需在同一上下文中将变量传递给 GCD。 嗯,恐怕你错了,它只返回对保留字符串的引用。而且我想只要“保留”修饰符在相应的 NSManagedObject 子类的属性中,它就会继续这样做。这是关于它的一些事情:***.com/questions/11411824/…。所以我在上面例子中的做法很容易出错。 有趣,我不知道,谢谢。您可以尝试使用 NSMutableString,不确定但可能有效

以上是关于将对 NSManagedObject 的属性的引用传递给后台线程的主要内容,如果未能解决你的问题,请参考以下文章

从 NSValueTransformer 内部引用 NSManagedObject 实体

创建将对象传递给实例方法的 NSPredicate

Core Data 没有触发 NSManagedObject 实例的错误作为应用程序委托的属性

检查 NSManagedObject 的对象图的变化

扩展 NSManagedObject 的删除方法

存储对已删除 NSManagedObject 的引用的局部变量会发生啥