我正在将我的项目转换为使用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应该解决的问题。
你知道更好的方法来实现同样的目标吗?
答案 0 :(得分:5)
此功能最好由NSCache
和NSDiscardableContent
处理。这使用显式start
和end
调用,允许您保持对不一定需要保留的事物的强引用(因为您将自动重新创建它们)。使用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中,您可以执行文件删除。