What are some of the NSCache's auto-removal policies? Apple's documentation does not mention them, and I experimentally discovered that NSCache does not respond to memory warning.
2 Answers
NSCache
does not respond to UIApplicationDidReceiveMemoryWarningNotification
, but it does automatically evict its objects in low memory situations, obviously using some other mechanism.
While I previously suggested observing UIApplicationDidReceiveMemoryWarningNotification
, this is not the case. No special handling for low memory situations is needed, as NSCache
handles this automatically.
Update:
As of iOS 7, the NSCache
not only doesn't respond to memory warnings, but it also does not appear to properly purge itself upon memory pressure, either (see NSCache crashing when memory limit is reached (only on iOS 7)).
I subclass NSCache
to observe UIApplicationDidReceiveMemoryWarningNotification
, and purge the cache upon memory warning:
@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
-
This is of course an old answer, but it no longer seems to be necessary to do this. Testing with `NSCache` in the simulator, and it always purges automatically when I "simulate a memory warning". – siburb Jan 11 '20 at 04:12
You're best off treating NSCache
as a black box, as much as you can.
From Caching and Purgeable Memory (emphasis mine):
When adding items to a cache, you can specify a cost value to be associated with each key-value pair. Call the
setTotalCostLimit:
method to set the maximum value for the sum of all the cached objects’ costs. Thus, when an object is added that pushes thetotalCost
above thetotalCostLimit
, the cache could automatically evict some of its objects in order to get back below the threshold. This eviction process is not guaranteed, so trying to manipulate thecost
values to achieve specific behavior could be detrimental to the performance of the cache. Pass in0
for thecost
if you have nothing useful, or use thesetObject:forKey:
method, which does not require a cost to be passed in.Note: The count limit and the total-cost limit are not strictly enforced. That is, when the cache goes over one of its limits, some of its objects might get evicted immediately, later, or never, all depending on the implementation details of the cache.

- 27,575
- 16
- 91
- 128
-
2Is it a good idea to observe on memory warning and purge the cache then? – Evil Nodoer Jun 04 '12 at 15:50
-
1@EvilNodoer Doing some experimentation, I discovered that while it does not respond to `UIApplicationDidReceiveMemoryWarningNotification`, it actually does evict its objects automatically in low memory situations (must be using some other mechanism). – Rob May 10 '13 at 13:39
-
@EvilNodoer BTW, I must retract my comment about `NSCache` responding to memory pressure, as this has changed in iOS 7. Observing `UIApplicationDidReceiveMemoryWarningNotification` would be prudent. See http://stackoverflow.com/questions/19546054/nscache-crashing-when-memory-limit-is-reached-only-on-ios-7 – Rob Dec 11 '13 at 16:02