Cocoa – When (not) to abuse NSUserDefaults

cocoalimitnsuserdefaultsoptions

I wonder what the guidelines are for:
1 – how often I can read from NSUserDefaults
2 – how much data I can reasonably store in NSUserDefaults

Obviously, there are limits to how much NSUserDefaults can be used but I have trouble determining what's reasonable and what isn't.

Some examples among others:

  • If my game has an option for the computer to be one of the players, I will use NSUserDefaults to save that boolean value. That much is clear. But is it also reasonable to access NSUserDefaults during my game every time I want to know whether the computer is a player or should I be using an instance variable for that instead? Assume here I need to check that boolean every second. Is the answer the same is it's 100 ms instead? What about every 10 s?

  • If my game has 50 moving objects and I want their positions and speeds to be stored when the user quits the app, is NSUserDefaults a reasonable place to store that data? What about 20 moving objects? What about 200?

Best Solution

I wonder what the guidelines are for: 1 - how often I can read from NSUserDefaults

quite regularly. expect the defaults' overhead to be similar to a thread-safe NSDictionary

2 - how much data I can reasonably store in NSUserDefaults

physically, more than you'll need it to. the logical maximum is how fast you need it to be, and how much space it takes on disk. also remember that this representation is read written to/from disk at startup/shut down and various other times.

If my game has an option for the computer to be one of the players, I will use NSUserDefaults to save that boolean value. That much is clear. But is it also reasonable to access NSUserDefaults during my game every time I want to know whether the computer is a player or should I be using an instance variable for that instead?

just add a const bool to the opponent object. zero runtime loss, apart from the memory, which will not be significant.

Assume here I need to check that boolean every second. Is the answer the same is it's 100 ms instead? What about every 10 s?

again, it's like a thread-safe NSDictionary (hashing). it will be fairly fast, and fast enough for reading at that frequency. whether it's the best design or not depends on the program. if it becomes huge, then yes the performance will suffer.

If my game has 50 moving objects and I want their positions and speeds to be stored when the user quits the app, is NSUserDefaults a reasonable place to store that data? What about 20 moving objects? What about 200?

it would be fine, although i would not read/write via user defaults during game-play; just save/load the state as needed.

i don't recommend saving all this in user defaults. just create a file representation for your game's state and use user defaults for what it's designed for. if it's huge and you write to it often, then the implementation may flush the state to disk regularly, which could take a relatively long time.

Related Question