Hi all,

I've been using an NSCache to store items that should be cached for performance 
reasons, since they are rather expensive to recreate. Understanding NSCache 
behaviour is giving me some headaches though.

I initialize my NSCache as follows:

        _cellCache = [[NSCache alloc] init];
        [_cellCache setDelegate:self];
        [_cellCache setEvictsObjectsWithDiscardedContent:NO];   // never evict 
cells

The objects held in the cache implement the NSDiscardableContent protocol. Now 
my problem is the NSCache class does not seem to be working correctly in a 
couple of instances.


1) First the smaller issue. NSCache's setCountLimit: states that:

"Setting the count limit to a number less than or equal to 0 will have no 
effect on the maximum size of the cache."

Can someone shed some light on what does this means? I.e., that the NSCache is 
maximal, and will issue discardContentIfPossible messages only when memory is  
required elsewhere? Or that the NSCache is minimal, and it will issue 
discardContentIfPossible messages immediately? 

The former makes more sense, but testing seems to indicate that the later is 
what is happening. If I log calls to the discardContentIfPossible method in my 
cached object, I see that it is being called almost immediately -- after only a 
2-3 dozen items have been added to the cache (each less than 0.5 MB).

Okay. So I try then to set a large count limit -- way more than I will ever 
need -- by adding the following line:

        [_cellCache setCountLimit:10000000];

Then the discardContentIfPossible messages are no longer sent almost 
immediately. I have to load a lot more content into the cache and use it for a 
while before these message start occurring which makes more sense.

So what is the intended behaviour here?


2) The larger issue. The documentation states:

"By default, NSDiscardableContent objects in the cache are automatically 
removed from the cache if their content is discarded, although this automatic 
removal policy can be changed. If an NSDiscardableContent object is put into 
the cache, the cache calls discardContentIfPossible on it upon its removal."

So I set the eviction policy to NO (above) so objects are never evicted. 
Instead, when discardContentIfPossible is called, I clear and release the 
internal data of the cached object according to special criteria. That is, I 
may decide not to actually clear and discard the data under certain 
circumstances (for example if the item has been very recently used). In such a 
scenario, I simply return from the discardContentIfPossible method not having 
discarded anything. The idea is that some other object that isn't recently used 
will get the message at some point, and it can discard it's content instead.

Now, interestingly, all seems to work great for a while of heavy use. Loading 
lots of content, placing and accessing objects in the cache, etc. After some 
time though, when I try to access an arbitrary object in the NSCache it's 
literally not there! Somehow it appears it has been removed -- even though I 
specifically set the eviction policy to NO.

Okay. So implementing the delegate method cache:willEvictObject: shows it never 
gets called. Which means the object is not actually getting evicted. But it's 
mysteriously disappearing from the NSCache since it can't be found on future 
lookups -- or somehow the key it was associated with is is no longer mapped to 
the original object. But how can that happen?

BTW, the key object that I'm associating with my value objects (CALayer's) is 
an NSURL container/wrapper, since I can't use NSURL's directly as NSCache 
doesn't copy keys -- only retains them, and a later NSURL key used for lookup 
might not be the *exact* original object (only the same URL string) that was 
initially used to load the cache with that object. Whereas with an NSURL 
wrapper/container, I can ensure it is the exact original key object that was 
used to add the original value object to the NSCache.

Can anyone shed some light on this?

Best,
Dalmazio





Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to