I want to store various objects in an NSCache and have them automatically get removed when a memory warning hits. So I wrote the following NSDiscardableContent implementation that I use to wrap instances I put into the values in an NSCache.
But I'm never seeing them get removed from the cache when I run "Simulate Memory Warning". Is there something wrong with my NSDiscardableContent implementation? Or do I need to do something else to make the cache drop the values when a memory warning occurs?
/** @brief generic implementation of the NSDiscardableContent for storing objects in an NSCache */
@interface GenericDiscardableObject : NSObject<NSDiscardableContent>
@property (nonatomic, retain) id object;
@property (nonatomic) NSUInteger accessCount;
+ (GenericDiscardableObject *)discardableObject:(id)ob;
@end
@implementation GenericDiscardableObject
@synthesize object, accessCount;
+ (GenericDiscardableObject *)discardableObject:(id)ob {
GenericDiscardableObject *discardable = [[GenericDiscardableObject alloc] init];
discardable.object = ob;
discardable.accessCount = 0u;
return [discardable autorelease];
}
- (void)dealloc {
self.object = nil;
[super dealloc];
}
- (BOOL)beginContentAccess {
if (!self.object)
return NO;
self.accessCount = self.accessCount + 1;
return YES;
}
- (void)endContentAccess {
if (self.accessCount)
self.accessCount = self.accessCount - 1;
}
- (void)discardContentIfPossible {
if (!self.accessCount)
self.object = nil;
}
- (BOOL)isContentDiscarded {
return self.object == nil;
}
@end
You typically use NSCache objects to temporarily store objects with transient data that are expensive to create. Reusing these objects can provide performance benefits, because their values do not have to be recalculated. However, the objects are not critical to the application and can be discarded if memory is tight.
The data stored for those cells are kept by NSCache, which stores data in-memory, so it's readily accessible by RAM.
As far as I can tell, the default behaviour of NSCache is to throw objects away when there is a memory warning.
So you can simply store your objects "naked" in your cache as if it was an NSDictionary, and they will be cleaned up when memory gets tight. You don't have to wrap them in a discardable object, or do anything else. E.g.
[myCache setObject:foo forKey:@"bar"]; // foo will be released if memory runs low
It's not very clear from the documentation, but as far as I can tell, the purpose of the <NSDiscardableContent>
content protocol is for implementing more complex behaviour whereby an object can release subcomponents when memory is low, without necessarily releasing itself.
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