Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSCache is always evicting image data when app enters background

Tags:

ios

nscache

This might be the expected behavior, but is not clearly stated by Apple.

I am using NSCache to cache some images for my UICollectionView. When I put the app in the background and open it again (immediately), all of my images are no longer in the NSCache.

Ideally, I would like the most recently loaded images to stay cached so that when the user re-opens the app they don't have to pay the cost of loading all of the images again. It seems like NSCache should allow a less aggressive caching policy.

I just wanted to post here for a sanity check and make sure I'm not missing anything obvious.

Otherwise, I'm going to have to implement my own cache that just keeps the last 25 loaded images in an NSMutableDictionary cache.

like image 545
chrysb Avatar asked Nov 11 '13 03:11

chrysb


People also ask

What is nscache and how does it work?

If an app’s memory is low, some items are automatically removed from the NSCache. You don’t need to handle this logic yourself. NSCache is thread-safe, meaning that you should not fear race conditions when accessing it from multiple threads. We can specify the desired maximum size (in bytes) of the cache and the number of objects put into it:

How do I load images from nscache to UIImageView?

If a cached image is found at the item number, retrieve it and assign it to the UIImageView. If there is no cached image at the item number, launch the image-loading task. Upon image retrieval, assign the image to the UIImageView. Store the loaded image inside the NSCache for future reuse.

What is a delegate in nscache?

The cache’s delegate. The delegate of an NSCache object implements this protocol to perform specialized actions when an object is about to be evicted or removed from the cache. func object(forKey: KeyType) -> ObjectType?

How do I remove a nsdiscardablecontent object from the cache?

By default, NSDiscardableContent objects in a cache are automatically removed 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.


2 Answers

It looks like you need to implement NSDiscardableContent protocol for the objects you put in NSCache. When objects in the cache don't conform to NSDiscardableContent, they're evicted on backgrounding the app according to this answer. https://stackoverflow.com/a/13579963

like image 76
Todd Avatar answered Oct 17 '22 03:10

Todd


The apple docs says:

The NSCache class incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. The system automatically carries out these policies if memory is needed by other applications. When invoked, these policies remove some items from the cache, minimizing its memory footprint.

So it removes some items, not all items. It depends on NSCache internal policies, available memory, device status, etc. Also, read a bit on NSDiscardableContent protocol as well.

From the docs:

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.

like image 45
Abhinav Avatar answered Oct 17 '22 04:10

Abhinav