NSCache and LRUCache
Is
NSCache
still a thing we like to use?
I’ve discussed this several times, but I don’t think I ever blogged about it. The problem I have with NSCache
is that its eviction strategy is not defined, and it’s definitely not LRU. When I tried to use NSCache
, it would destroy the performance of my app because I would fetch objects from the database, put them in the cache, and then find them immediately evicted, with the cache remaining full of older objects that I didn’t care about. I guess it could be useful as a threadsafe dictionary if you know that you won’t be exceeding the capacity. But often when I want a cache it’s because I need to limit the memory consumption, and in that situation NSCache
just doesn’t work for me.
I ended up writing my own LRU cache, combining a Swift Dictionary
with a linked list that tracks which keys were accessed most recently. Nick Lockwood made an open-source solution called LRUCache, converging on a similar design. (There were some interesting discussions in building it that have unfortunately been deleted.)
The main thing to be aware of if you’re writing your own is that if you let ARC deallocate your linked list nodes automatically it will explode. ARC uses recursion to follow the references, so if your list is too big it will overflow the stack. You can fix this by manually deleting list nodes using a loop. Or, if your list is only used by the cache, you can make the list pointers unowned
and let the dictionary do the retaining.
Recently, I needed to add caching to one of the iOS apps I’m working on. While researching a few possible ways how to go about this I came across a great article written by John Sundell (a pretty common occurrence when searching for Swift topics on the web, thanks John!). While the basic concept he describes in the article worked quite well for my needs, there was one major problem with the approach:
NSCache
will drop your objects like hot potatoes as soon as your app gets backgrounded.[…]
So if you don’t want the system to evict all objects from your cache when your app gets backgrounded, make sure your objects implement the
NSDiscardableContent
protocol.
Previously:
1 Comment RSS · Twitter · Mastodon
Is anyone using NSCache with success? Projects on GitHub that use it seem to be ignorant of its issues. Presumably, LLMs will emit code that uses it and spread the ignorance.
NSCache is quintessential Apple developer experience: Gets WWDC hype -> doesn't meet dev expectations -> never gets updated -> everyone writes their own.