自动引用计数(ARC)和retainCount

时间:2012-03-02 17:09:30

标签: objective-c cocoa-touch ios5 automatic-ref-counting retaincount

我正在将我的项目转换为使用ARC,并遇到了一个特殊问题。我有一个类来管理从网络下载的文件缓存。每个文件都存储在iPhone文件系统中,相关对象保存在我的管理器类中。 其他想要使用文件的对象,请求我的经理获取缓存对象,并在需要该文件时保留该文件。

但有一段时间,经理会清理缓存,删除旧文件。当然,它不应该删除当时正在使用的文件。在ARC之前,我通过使用关联对象的retainCount来检测到它:

// if retainCount is 1 then only the cache has a reference to it
if( obj.retainCount <= 1 ) {
    [obj deleteFile];
    [cache removeObject:obj];
}

完美无缺[并且是的,我知道有关retainCount不可靠性的警告,但根据我的经验,如果retainCount&gt; 1你确定不止一个对象保留了它]

但是,使用ARC时,不允许再使用retainCount。我可以引入自己的保留计数机制,并要求所有使用文件的对象明确保留和释放文件对象。但那是错误的,而且这正是ARC应该解决的问题。

你知道更好的方法来实现同样的目标吗?

3 个答案:

答案 0 :(得分:5)

此功能最好由NSCacheNSDiscardableContent处理。这使用显式startend调用,允许您保持对不一定需要保留的事物的强引用(因为您将自动重新创建它们)。使用NSCache也可以获得其他优势,例如即使您被暂停也可以自动转储可丢弃内容。如果没有NSCache之类的内容,那么当内存变低而不是让你转储多余的缓存时,你就会被杀死。

那就是说,你已经建立了另一个系统。这个特殊问题是weak引用的内容。您的缓存应该保持对对象的弱引用,而不是强引用。 Non-retaining array for delegates中讨论了几种方法。我个人更喜欢NSValue解决方案。批准的答案听起来很简单,但你需要很好地理解ARC和CFArray才能正确使用它。 NSValue解决方案不那么棘手。

理想情况下,如果您的文件对象知道它们已被缓存,则可以告诉缓存在dealloc期间删除它们。否则,您可以定期清除阵列中的空值。

答案 1 :(得分:0)

只需在对象的实现中设置一些int变量,每次保留对象时递增它,并覆盖其dealloc方法以减少它。保留计数相同,但它只适用于自定义对象。

答案 2 :(得分:0)

不确定这是否适用于您的需求,但您知道Associative References吗?这些允许您将从属对象附加到主对象,以便只要主人生活,从属对象就会存在。它不仅允许将对象附加到您无法控制的对象上,还可以了解它们的生命周期结束。

我想知道你是否可以通过附加一个自定义类对象来监视你的“obj”,如果“obj”被释放,那么将调用自定义类'dealloc'。在该自定义dealloc中,您可以执行文件删除。