Friday, May 9, 2025

NSCache and LRUCache

Christian Tietze:

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.

Matthias Maurberger:

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.

Leave a Comment