Nscache Emptied When App Enters Background

NSCache emptied when app enters background

Think you need to ensure that objects placed in cache conform to NSDiscardableContentProtocol to have desired results. From the NSCache Class Reference:

A common data type stored in NSCache objects is an object that
implements the NSDiscardableContent protocol. Storing this type of
object in a cache has benefits, because its content can be discarded
when it is not needed anymore, thus saving memory. 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.

Does NSCache gets automatically emptied when the app is force quitted?

Yes it does that, for some reason it instantly removes data from cache when app enters background even if there is no memory pressure. To fix this you have to tell NSCache that your data should not be discarded.

What you could do is something like:

class ImageCache: NSObject , NSDiscardableContent {

public var image: UIImage!

func beginContentAccess() -> Bool {
return true
}

func endContentAccess() {

}

func discardContentIfPossible() {

}

func isContentDiscarded() -> Bool {
return false
}
}

and then use this class in NSCache like the following:

let cache = NSCache<NSString, ImageCache>()

After that you have to set the data which you cached earlier:

let cacheImage = ImageCache()
cacheImage.image = imageDownloaded
self.cache.setObject(cacheImage, forKey: "yourCustomKey" as NSString)

And finally retrieve the data:

if let cachedVersion = cache.object(forKey: "yourCustomKey") {
youImageView.image = cachedVersion.image
}

UPDATE

This was already answered by Sharjeel Ahmad. See this link for reference.

Use a global NSCache or one per class?

It obviously depends, but I would generally vote for one cache for each type of cached object. That way, you can have different countLimit values for each, e.g. to specify things like "keep the 50 most recently rendered thumbnails", "keep the 5 most recently downloaded large images", "keep the 10 most recently downloaded PDFs", etc.

For really computationally expensive tasks, I also employ two tier caching, NSCache for optimal performance, and saving to a temporary/cache directory in the local file system to avoid costly download cycles while not consuming RAM.

NSCache is not evicting data

From the doc (Emphasis mine): 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.

Apple does not state that the memory will be freed on memory warning - in my experience, the cache is most often purged when the app goes to background or when you add more large elements.



Related Topics



Leave a reply



Submit