2

我正在将我的项目转换为使用ARC,并遇到了一个特殊问题。我有一个类管理从网络下载的文件缓存。每个文件都存储在iPhone文件系统中,并且关联的对象保存在我的经理类中。 其他想要使用文件的对象,向缓存对象请求我的管理器,并在需要文件的时候保留它。自动引用计数(ARC)和retainCount

但有一段时间,管理器清理缓存,删除旧文件。当然,它不应该删除当时正在使用的文件。 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应该解决的问题。

你知道更好的方法来实现同样的事情吗?

+0

唯一值得一提的是retainCount:http://stackoverflow.com/a/4636477/106435 – vikingosegundo 2012-03-02 17:30:39

+0

你有没有考虑过[NSCache](https://developer.apple.com/library/ios/) #文档/可可/参考/ NSCache_Class /参考/的reference.html)? – Caleb 2012-03-02 17:39:27

+0

@Caleb:Rob也给出了这个答案。我不知道它,并会研究它。 – fishinear 2012-03-02 18:06:36

回答

5

此功能最好由NSCacheNSDiscardableContent处理。它使用明确的startend电话,让您保持对事情你不一定需要保持周围(因为你会自动重新创建它们)强引用。使用NSCache也可以获得其他优势,例如即使在暂停时也会自动转储可丢弃内容。没有像NSCache这样的东西,当内存变得很低时,你会被杀死,而不是让你转储多余的缓存。

也就是说,你已经建立了另一个系统。这个特定的问题是weak引用的目的。您的缓存应该保留对对象的弱引用,而不是强引用。在Non-retaining array for delegates中讨论了几种方法。我个人比较喜欢NSValue解决方案。获得批准的答案听起来非常简单,但您需要理解ARC和CFArray才能正确使用它。 NSValue解决方案要简单得多。

理想的情况下,如果你的文件对象知道自己被缓存,他们可以告诉缓存他们dealloc时将其删除。否则,您可以定期清除数组中的空值。

+0

NSCache是​​一个很好的提示,我不知道这一点。我一定会考虑我是否可以使用它。我首先想到的弱引用是我无法使用的:这意味着当不再使用时,我的对象和关联文件将被删除。我有一个缓存完全可以避免这种情况。但考虑一下:我可以让文件对象被弱引用清除,但保留这些文件。然后清理代码可以检查哪些引用是零,并删除关联的文件。嗯,可能会奏效。谢谢! – fishinear 2012-03-02 17:53:39

+0

我看着NSCache,坦率地说它看起来不太有用。尽管它表示它“合并了各种自动清除策略”,但似乎没有办法设置要使用的策略。例如,如果您知道如何设置LRU(或LFU)删除策略,请告诉我。快速的互联网搜索没有得到有用的答案。 – fishinear 2012-03-02 20:30:18

0

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

+0

那么,我的文件对象的dealloc不会被调用,因为我的缓存仍然有一个对它的引用。还是你的意思是使用文件对象的所有不同对象的释放?这将与建立我自己的参考计数系统相同,不是吗? – fishinear 2012-03-02 17:30:27

+0

他可能意味着在释放而不是释放时递减它。我不确定这是否会起作用,因为我相信ARC会绕过正常的保留和释放方法,甚至可能无法覆盖它们。 – UIAdam 2012-03-02 17:33:32

+0

@UIAdam,在ARC下,根本不需要调用retain或release。 – 2012-03-02 17:45:01

0

不知道这是否可以应用到你的需求,但你知道Associative References?这些允许您将从属对象附加到主对象上,以便从属对象在主对象存在的情况下一直存在。不仅可以将对象附加到您无法控制的对象,还可以了解它们的使用期限。

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

+0

我不知道关联引用,它们非常令人印象深刻,特别是与类别一起。谢谢你的提示!但是,在这种情况下,它们不适用,因为我可以控制原始对象。无论我在关联对象中做什么,我都可以在原始对象的(dealloc)中执行操作。而且我已经在原始对象中实现了明确的引用计数,所以这个问题不再是现在的问题。 – fishinear 2012-11-13 10:55:26

相关问题