5

When I'm setting up the default preferences for my app, I'm doing the following:

1) Reading Root.plist from inside Settings.bundle into a dictionary.

2) I test if a preference is set, and if not I'm registering my defaults dictionary via [NSUserDefaults standardUserDefaults] registerDefaults:]

Problem is, defaults registered with registerDefaults: do not go to the persistent store, so if the user never changes their preferences I am reading my default preferences and registering them with NSUserDefaults every time the app launches.

Instead of using registerDefaults: I could use setValue:forKey: and have my default setting go to the persistent store, bypassing the need to build & register a dictionary on each launch. However, Apple's documentation and sample code both point to registerDefaults:.

So I'm trying to figure out when and why I should use registerDefaults: and when/why I should use setValue:forKey: instead?

gabrielk
  • 573
  • 6
  • 11
  • 1
    I found this related question: [What is the use of -[NSUserDefaults registerDefaults:]?](http://stackoverflow.com/questions/4931167/what-is-the-use-of-nsuserdefaults-registerdefaults) While the answers explain the differences, they still don't really say why you should use one over the other. (The answers seem to ignore my question about persistence.) – gabrielk Feb 06 '12 at 20:05

1 Answers1

5

Problem is, defaults registered with registerDefaults: do not go to the persistent store, so if the user never changes their preferences I am reading my default preferences and registering them with NSUserDefaults every time the app launches.

Yes. Why is that a problem? Why write to disk things you have in the code already?

Instead of using registerDefaults: I could use setValue:forKey: and have my default setting go to the persistent store, bypassing the need to build & register a dictionary on each launch. However, Apple's documentation and sample code both point to registerDefaults:.

Only if you first checked "is this value set? No? OK, now set it." That's more code and cost than just using registerDefaults:.

You should use registerDefaults: to set the defaults. You should use setValue:forKey: to save values that are actively set.

Remember also that NSUserDefaults exists on Mac as well. There, the user can directly access the settings with the defaults command, so the program is not the only entity that can modify this store.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • I suppose it's not that it's a problem, it just seems awfully redundant. If I set up defaults, and the user doesn't like them, he can change them and the change is saved...and I still have to keep setting up the defaults. Likewise, if a user is happy with the defaults and has no reason to save them...I still have to keep setting up the defaults. Makes more sense to me to save the defaults, since the stored default would get overridden by the user anyway. I still don't see a solid case for using registerDefaults: – gabrielk Feb 06 '12 at 20:38
  • It's especially strange to me because the defaults I want are stored in the Settings.bundle .plist file, but they're not used as actual defaults (more like a hint to the GUI when displaying the choices?). – gabrielk Feb 06 '12 at 20:40
  • 1
    Other than the fact that it takes more code to store the defaults in the store (since you first have to test whether they're already set), saving them to the store makes it impossible to change the default in future upgrades, and wastes space if you delete a setting during an upgrade. But the "it's much more code to check all the defaults and then set them" really is the biggest win to developers of `registerDefaults:`. – Rob Napier Feb 06 '12 at 20:42
  • 1
    Settings.bundle is a completely different thing, and is iOS specific (NSUserDefaults is very old, and comes from Mac). It would be nice if the two were integrated. But many apps do not use `Settings.bundle` due to all its limitations. – Rob Napier Feb 06 '12 at 20:43
  • Thanks for the clarifications. It actually makes a lot more sense now. – gabrielk Feb 06 '12 at 22:34
  • @RobNapier "Why write to disk things you have in the code already?" So registerDefaults does not write to disk ? – onmyway133 Nov 07 '13 at 09:50
  • Correct. `registerDefaults` initializes values for the `NSUserDefaults` in the current process. – Rob Napier Nov 07 '13 at 16:43