NSCache is a rarely used tool which actually looks quite useful. I created a simple experiment to see how it works and it looks like it does not auto-evict data in low memory situations (or I am doing something wrong!)
- (void)viewDidLoad
{
_testCache = [[NSCache alloc] init];
// Allocate 600 MB of zeros and save to NSCache
NSMutableData* largeData = [[NSMutableData alloc] init];
[largeData setLength:1024 * 1024 * 600];
[_testCache setObject:largeData forKey:@"original_Data"];
}
- (IBAction)buttonWasTapped:(id)sender {
// Allocate & save to cache 300 MB each time the button is pressed
NSMutableData* largeData = [[NSMutableData alloc] init];
[largeData setLength:1024 * 1024 * 300];
static int count = 2;
NSString* key = [NSString stringWithFormat:@"test_data_%d", count++];
[_testCache setObject:largeData forKey:key];
NSMutableData* dataRecoveredFromCache = [_testCache objectForKey:@"original_Data"];
if (dataRecoveredFromCache) {
NSLog(@"Original data is ok");
} else {
NSLog(@"Original data is missing (purged from cache)");
}
}
So I ran the app in the simulator, and taped the button a few times however no items were evicted... The app eventually crashed:
2012-07-17 14:19:36.877 NSCacheTest[15302:f803] Data is ok
2012-07-17 14:19:37.365 NSCacheTest[15302:f803] Data is ok
2012-07-17 14:19:37.861 NSCacheTest[15302:f803] Data is ok
2012-07-17 14:19:38.341 NSCacheTest[15302:f803] Data is ok
2012-07-17 14:19:38.821 NSCacheTest[15302:f803] Data is ok
NSCacheTest(15302,0xac0942c0) malloc: *** mmap(size=393216000) failed (error code=12)
*** error: can't allocate region
From the doc (Emphasis mine): The NSCache class incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. The system automatically carries out these policies if memory is needed by other applications. When invoked, these policies remove some items from the cache, minimizing its memory footprint.
Apple does not state that the memory will be freed on memory warning - in my experience, the cache is most often purged when the app goes to background or when you add more large elements.
Here's quoted docs ...
The NSCache class incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. The system automatically carries out these policies if memory is needed by other applications. When invoked, these policies remove some items from the cache, minimizing its memory footprint.
... as you can see it states that it removes some items, not all items. It depends on NSCache
internal policies, available memory, device status, etc. You shouldn't worry about these policies.
You can control them with countLimit
, totalCostLimit
properties and you can add object with cost, look at setObject:forKey:cost:
.
Also you can evict objects by yourself. Add NSDiscardableContent
protocol implementation to your objects and setEvictsObjectsWithDiscardedContent
: to YES
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With