9

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.

Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
chrysb
  • 1,351
  • 2
  • 13
  • 20

3 Answers3

5

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

Community
  • 1
  • 1
Todd
  • 239
  • 2
  • 11
3

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.

Abhinav
  • 37,684
  • 43
  • 191
  • 309
  • I tested it such that I put a few images in the cache, put the app in the background and brought it back in the foreground and those images appear to have been evicted. I'm caching the images after receiving them from AFNetworking's setImageWithURLRequest. I wonder if that has anything to do with it? Maybe something else is releasing the images when the app goes into the background? – chrysb Nov 11 '13 at 04:27
  • I agree and this is what is mentioned in the docs as well. You might want to use some session variables (like singleton class) and set them instead. – Abhinav Nov 11 '13 at 04:29
  • Thanks - I will try more and report back. – chrysb Nov 11 '13 at 19:08
  • I was also having same.. so I used NSDiscardableContent for not to evict cached image from NSCache when app goes into background I created sample app https://github.com/SurendraK11/CachingImage CacheItem is geneic class, confirms NSDiscardableContent. Main objective of this class is to wrap item in stored property – Surendra Kumar May 09 '19 at 12:52
0

I was also having same issue, “cached images in NSCache evicted when app goes into background”. I did create an example to handle this issue, available in github https://github.com/SurendraK11/CachingImage/tree/master/CachingImages

Import thing is to not here, UIImage is not cached into NSCache directly. This is wrapped into CacheItem generic class which confirm NSDiscardableContent where isContentDiscarded return false and beginContentAccess return true

More information about NSDiscardableContent https://developer.apple.com/documentation/foundation/nsdiscardablecontent

Surendra Kumar
  • 237
  • 2
  • 9