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 (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