NSCache, always being overshadowed by
NSMutableDictionary. It's as if no one knew it was there, ready to provide all of that garbage collection behavior that developers take great pains to re-implement themselves.
NSCache is basically just an
NSMutableDictionary that automatically evicts objects in order to free up space in memory as needed. No need to respond to memory warnings or contrive a cache-clearing timer mechanism. The only other difference is that keys aren't copied as they are in an
NSMutableDictionary, which is actually to its advantage (no need for keys to conform to
<NSCopying>). If developers only knew...
But you're not like other devs, right? You won't overlook
NSCache, will you?
That's not to say that there aren't a few warts and inexplicable caveats--far from it.
NSCache is kind of a hot mess.
setObject:forKey:cost:, for example. It's the same
setObject:forKey: method as before, but with this
cost parameter. What is that, you ask? Well, even the documentation isn't quite sure:
The cost value is used to compute a sum encompassing the costs of all the objects in the cache. When memory is limited or when the total cost of the cache eclipses the maximum allowed total cost, the cache could begin an eviction process to remove some of its elements.
Alright, so far so good...
However, this eviction process is not in a guaranteed order. As a consequence, if you try to manipulate the cost values to achieve some specific behavior, the consequences could be detrimental to your program.
Huh? So what's the point, then?
Typically, the obvious cost is the size of the value in bytes. If that information is not readily available, you should not go through the trouble of trying to compute it, as doing so will drive up the cost of using the cache.
So wait, what's a non-obvious cost value? Any guidelines for what a memory limit should be? How about an order of magnitude, even? "Arbitrarily guess wrong and suffer bad performance" doesn't sound too good...
Pass in 0 for the cost value if you otherwise have nothing useful to pass, or simply use the setObject:forKey: method, which does not require a cost value to be passed in.
Read: don't use this method unless you work at Apple and know the original author personally.
There's also a whole part about controlling whether objects are automatically evicted with
<NSDiscardableContent>, but it will probably just cause you more problems.
That all said, developers should be using
NSCache a lot more than they currently are. Anything in your project that you're already calling a "cache" and either using
NSMutableDictionary or implementing yourself would be prime candidates for replacement. Just be sure to stick to the classics: