2

我正在将我的项目转换为使用 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 > 1,你肯定知道不止一个对象保留了它]

但是,在 ARC 中,您不能再使用 retainCount。我可以引入我自己的保留计数机制,并要求所有使用文件的对象显式保留和释放文件对象。但这很容易出错,而这正是 ARC 应该解决的问题。

您知道实现相同目标的更好方法吗?

4

3 回答 3

5

此功能最好由NSCache和处理NSDiscardableContent。这使用显式startend调用,它允许您维护对您不一定需要保留的事物的强引用(因为您将自动重新创建它们)。使用NSCache它还可以为您带来其他优势,例如即使在您被暂停时也会自动转储可丢弃的内容。如果没有类似的东西NSCache,当内存不足时你会被杀死,而不是让你转储多余的缓存。

也就是说,您已经构建了另一个系统。这个特殊的问题就是weak引用的目的。您的缓存应该保持对对象的弱引用而不是强引用。代表的非保留数组中讨论了几种方法。我个人更喜欢这个NSValue解决方案。批准的答案听起来既好又简单,但是您需要CFArray非常了解 ARC 才能正确使用它。NSValue解决方案不那么棘手。

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

于 2012-03-02T17:39:28.733 回答
0

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

于 2012-03-02T17:17:55.127 回答
0

不确定这是否可以满足您的需求,但您知道关联引用吗?这些允许您将从属对象附加到主对象,以便从属对象与主对象一样存在。这不仅允许将对象附加到您无法控制的对象上,而且您还可以了解它们的使用寿命。

我想知道您是否可以通过将自定义类对象附加到它来使用它来监视您的“obj”,并且如果“obj”被释放,则将调用该自定义类的 dealloc。然后,在该自定义 dealloc 中,您可以执行文件删除。

于 2012-11-12T21:32:20.347 回答