Re: Odd NSCache Eviction Behaviour
Re: Odd NSCache Eviction Behaviour
- Subject: Re: Odd NSCache Eviction Behaviour
- From: Ken Thomases <email@hidden>
- Date: Mon, 04 Apr 2011 14:37:45 -0500
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.)
> 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.)
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
_______________________________________________
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