Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use NSCache with a generic NSDiscardableContent implementation

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
like image 389
marcprux Avatar asked Sep 05 '11 21:09

marcprux


People also ask

When to use NSCache?

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.

Where is NSCache stored?

The data stored for those cells are kept by NSCache, which stores data in-memory, so it's readily accessible by RAM.


1 Answers

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.

like image 77
Nick Lockwood Avatar answered Sep 19 '22 00:09

Nick Lockwood