Re: Odd NSCache Eviction Behaviour
Re: Odd NSCache Eviction Behaviour
- Subject: Re: Odd NSCache Eviction Behaviour
- From: Dalmazio Brisinda <email@hidden>
- Date: Tue, 05 Apr 2011 16:01:57 +0700
On 2011-04-05, at 2:37 AM, Ken Thomases wrote:
> On Apr 4, 2011, at 11:34 AM, Dalmazio Brisinda wrote:
>
>> 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.
>
> I don't think that's what that means. Setting it to YES (or leaving it at its default), means that the NSCache will more-or-less-immediately evict NSDiscardableContent objects whose contents are discarded, without regard for memory pressure (or count or cost). Setting it to NO, does not mean that objects are not evicted. It simply means that NSCache isn't "eager" about evicting NSDiscardableContent objects whose content have been discarded. It will let them stick around until the normal eviction process is provoked.
>
> Put another way, NSDiscardableContent and NSCache are independent. They can be used separately from one another. NSDiscardableContent objects merely support the notion of discarding their contents, whether or not they are in an NSCache. (NSPurgeableData is one type of discardable object, and it coordinates with the OS to discard its contents under memory pressure. For custom classes adopting NSDiscardableContent, you'd have to make your own arrangements for content to be discarded.) NSCache will evict its content whether or not they are discardable. However, NSCache is aware of NSDiscardableContent and will, as an optional optimization, eagerly evict discarded objects.
>
> I don't know that there's a real good solution for something like NSCache but for which you can prevent it from evicting stuff. I suppose, you can put stuff in it, but also keep it retained elsewhere. Then, you can use the delegate method to learn when NSCache believes there's reason to evict things. That will give you some visibility into the system's mechanism for tracking memory pressure. However, that won't actually let you prevent the item from being evicted from the cache. It just means the eviction will not lead to the deallocation of the item. (An alternative approach would be to retain the object within the delegate method if you want to keep it.)
>
> The problem is, once the item is evicted from the cache, you'd like to re-add it to make sure the cache has a true representation of what you're keeping around. But if you re-add it immediately, that might cause NSCache to immediately re-evict it. (Also, it's not legal to re-add it from the delegate callback.)
Thanks for that explanation. It seems I misunderstood the NSCache documentation.
It's too bad that NSCache doesn't have an LRU or similar user-definable eviction policy setting. This is all that would be needed to make it much more useful generally. If resources are low, it could still evict all objects it needs to -- but at least we would have the option of having this done in an pre-defined order that's friendly to a variety of application needs. The current approach severely limits the utility of this type of cache. But seeing as it's a relatively new to Cocoa, I guess I should be grateful it's available at all, even if in it's current rather limited form.
I guess I'll have to rethink my design. Pity. NSCache looked so promising.
>
>
>> Okay. So implementing the delegate method cache:willEvictObject: shows it never gets called. Which means the object is not actually getting evicted.
>
> Another explanation is that you may have a typo in your definition of that method, such that NSCache is not finding it via respondsToSelector:. (Why that delegate protocol method is @optional is beyond me. Had it been @required, such bugs would not be possible.)
Hmm. Well you were right -- this turned out to be developer error. Though I implemented the correct method, I hadn't conformed to the protocol. And it seems that NSCache is checking protocol conformance in addition to respondsToSelector.
>
> It's also possible that was due to NSCache believing that the items were discarded. Maybe for those, it feels free to evict without calling the delegate. On the other hand, it may just be a bug. You might look into libcache/cache.h, which is the low-level API for the same sort of functionality. That might avoid any bug that NSCache might have in this respect.
>
> Regards,
> Ken
>
I'll have a closer look at libcache/cache.h and see if I can bend it to my application needs. Not sure if I want to re-implement NSCache to support user-defined eviction policies at this time.
Thanks for your help.
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