I am confused about the search list feature in NSUserDefaults
. The class reference says about the standardUserDefaults
class method that it sets up a standard search list consisting of five domains. The docs for that method also imply that this search list can be changed (boldness added by me):
Subsequent modifications to the standard search list remain in effect even when this method is invoked again—the search list is guaranteed to be standard only the first time this method is invoked.
Let's also look at the docs for init
:
Return Value: An initialized NSUserDefaults object whose argument and registration domains are already set up.
Discussion: This method does not put anything in the search list.
In my understanding this is a contradiction: Either the search list is empty, or it contains entries for the argument and registration domains.
Anyway, I did a bit of experimentation:
NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults];
// We get nil, which is expected
NSLog(@"test 1: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSDictionary* registrationDomainDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42] forKey:@"foo"];
[standardUserDefaults registerDefaults:registrationDomainDefaults];
// We get 42, which is expected
NSLog(@"test 2: expecting 42, getting %@", [standardUserDefaults objectForKey:@"foo"]);
[standardUserDefaults removeSuiteNamed:NSRegistrationDomain];
[standardUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// Here we get 42!
NSLog(@"test 3: expecting nil, getting %@", [standardUserDefaults objectForKey:@"foo"]);
NSUserDefaults* myUserDefaults = [[NSUserDefaults alloc] init];
// Here we also get 42!
NSLog(@"test 4: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
[myUserDefaults removeSuiteNamed:NSRegistrationDomain];
[myUserDefaults removeVolatileDomainForName:NSRegistrationDomain];
// We still get 42 *sigh*
NSLog(@"test 5: expecting nil, getting %@", [myUserDefaults objectForKey:@"foo"]);
As you can see, I am trying to remove NSRegistrationDomain
from the search list, by invoking both removeSuiteNamed:
and removeVolatileDomainForName:
. This does not work, at least not on iOS where I ran the tests, but I assume it's the same on Mac OS X. So these are my questions:
NSUserDefaults
object? Note that it does not necessarily have to be the object returned by standardUserDefaults
, I would be happy to create my own object. In case it matters: I am particularly interested in getting rid of NSRegistrationDomain
.NSUserDefaults
about adding/removing suites and persistent/volatile domains is about user-defined domains?NSUserDefaults
object?I suspect I already know the answers (no, yes, and no), but at least I am looking for someone with more experience to confirm my suspicions.
Storing Default Objects The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs. These methods are described in Setting Default Values.
All the contents saved by NSUserDefaults is saved inside a plist file that can be found under Library -> Preferences -> $AppBundleId.
The NSUserDefaults class is thread-safe.
There isn't a way to check whether an object within NSUserDefaults is empty or not. However, you can check whether a value for particular key is nil or not.
To get rid of a domain like NSRegistrationDomain
, you should use removeVolatileDomainForName:
. However, this will not work with NSRegistrationDomain
and NSArgumentDomain
. These two cannot be removed. Try to register your own domain with setVolatileDomain:forName:
instead. You'll be able to remove this one.
I believe that in the five domains of the standardUserDefaults, you can remove your own domain with removePersistentDomainForName:
, passing your bundle identifier. But I've not tried this out.
Since NSGlobalDomain
is persistent and you can only pass your own bundle identifier to removePersistentDomainForName:
, I believe you can't remove NSGlobalDomain
. Again, this is untested.
I believe so, except for the persistent domain with your bundle identifier.
No, but using -volatileDomainNames
should be sufficient for most purposes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With