NSCache自动删除策略

时间:2012-06-02 00:16:32

标签: iphone objective-c ios cocoa-touch

NSCache的自动删除政策有哪些? Apple的文档没有提及它们,我通过实验发现NSCache没有响应内存警告。

2 个答案:

答案 0 :(得分:9)

NSCache不响应UIApplicationDidReceiveMemoryWarningNotification,但它会在低内存情况下自动驱逐其对象,显然使用其他一些机制。

虽然我之前建议观察UIApplicationDidReceiveMemoryWarningNotification,但事实并非如此。由于NSCache会自动处理这种情况,因此无需对内存不足的情况进行特殊处理。


更新

从iOS 7开始,NSCache不仅没有响应内存警告,而且在内存压力下也似乎没有正确清除自己(参见NSCache crashing when memory limit is reached (only on iOS 7))。

我将NSCache子类化为观察UIApplicationDidReceiveMemoryWarningNotification,并在内存警告时清除缓存:

@interface AutoPurgeCache : NSCache
@end

@implementation AutoPurgeCache

- (id)init
{
    self = [super init];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];

    // if not ARC, also
    //
    // [super dealloc];
}

@end

答案 1 :(得分:7)

你最好将NSCache视为一个黑盒子,尽可能多。

来自Caching and Purgeable Memory(强调我的):

  

将项目添加到缓存时,您可以指定与每个键值对关联的成本值。调用setTotalCostLimit:方法设置所有缓存对象成本总和的最大值。因此,当添加一个将totalCost推到totalCostLimit之上的对象时,缓存可以自动驱逐其某些对象以便回到阈值以下。 此驱逐过程无法保证,因此尝试操纵cost值以实现特定行为可能会对缓存的性能产生不利影响。 传入{{如果您没有任何用处,请使用0,或使用cost方法,该方法不需要传入费用。

     

注意:未严格执行计数限制和总费用限制。也就是说,当缓存超过其中一个限制时,其某些对象可能会立即被驱逐,之后或永远不会被驱逐,这取决于缓存的实现细节。