Odd NSCache Eviction Behaviour
Odd NSCache Eviction Behaviour
- Subject: Odd NSCache Eviction Behaviour
- From: Dalmazio Brisinda <email@hidden>
- Date: Mon, 04 Apr 2011 23:34:02 +0700
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 (email@hidden)
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:
This email sent to email@hidden