潜在的引用计数问题,除非在后台线程中获取新的引用

在阅读Marcus S. Zarra(优秀) 核心数据:iOS,OS X和iCloud (第2版)的数据存储和管理 (如果可能的话)后,我有第二个问题。

本书的部分异步添加NSPersistentStore包含这段代码(摘录):

dispatch_queue_t queue; queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ // ... NSPersistentStoreCoordinator *coordinator = nil; coordinator = [[self managedObjectContext] persistentStoreCoordinator]; // ... }); 

它还包含以下解释:

我们获得NSPersistentStoreCoordinator的新参考的原因之一是安全性。 如果我们要使用外部方法的引用,我们将增加NSPersistentStoreCoordinator的保留计数,并可能导致不必要的引用计数问题。

这个潜在的引用计数问题的本质是什么?

我理解,如果调度块将引用外部作用域的NSPersistentStoreCoordinator ,它将保留该协调器(将其引用计数增加1),然后只有在块完成执行后才能释放它。 如果后台线程从未执行或者它不会终止,则引用计数问题将保留。

这就是它的全部,还是有更微妙的案例也会构成参考计数问题,并且可能在这种情况下实现?

就目前而言,我不会(显着)关注这个特定情况下的潜在引用计数问题(为立即执行而调度的简单后台操作)但可能我遗漏了一些东西。

在这个例子中,块本身可以相对较晚地执行(许多其他代码可以在此块之前执行)。 这意味着上下文或商店协调员可能会发生很多事情,并且假设商店协调员在块开始执行之前和之后甚至不是同一个对象。

通过调用管理器来检索协调器的新引用,您首先要确保获得最新的协调器以及保持当前协调器不从块中取出。 如果您要从块外部重用协调器,那么协调器将被保留,并且可能产生(尽管不太可能)诸如内存膨胀之类的问题。 如果一切都变坏并且块永远不会执行,那么协调器将永远保留,并且您有内存泄漏。

这只是一个很好的做法。