9

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

4

2 回答 2

10

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

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


更新:

从 iOS 7 开始,NSCache不仅不响应内存警告,而且它似乎也没有在内存压力下正确清除自身(请参阅达到内存限制时 NSCache 崩溃(仅在 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
于 2013-05-09T04:23:17.727 回答
7

你最好尽可能地把NSCache它当作一个黑匣子。

来自缓存和可清除内存(强调我的):

将项目添加到缓存时,您可以指定与每个键值对关联的成本值。调用该setTotalCostLimit:方法设置所有缓存对象成本总和的最大值。因此,当添加的对象totalCost超过 时totalCostLimit,缓存可以自动驱逐它的一些对象,以便回到阈值以下。无法保证此逐出过程,因此尝试操纵cost值以实现特定行为可能会损害缓存的性能。如果没有什么有用的就传入,或者使用不需要0传入代价的方法。costsetObject:forKey:

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

于 2012-06-02T00:44:37.353 回答