Can someone explain the search list function in NSUserDefaults?

I am confused about the search list function in NSUserDefaults . The class reference talks about the standardUserDefaults class method, which sets a standard search list of five domains. The docs for this method also imply that this search list can be changed (courage added by me):

Subsequent modifications to the standard search list remain valid even when this method is called again - the search list is guaranteed to be standard only when this method is first called.

Let's also look at the docs for init :

Return value: An initialized NSUserDefaults object whose arguments and registration domains are already configured.

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 arguments and registration domains.

Anyway, I experimented a bit:

 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 calling both removeSuiteNamed: and removeVolatileDomainForName: This does not work, at least not on iOS, where I ran the tests, but I assume it is the same on Mac OS X. So these are my questions:

  • On iOS, is there a way to remove one of the five standard domains from the NSUserDefaults object's search list? Note that this does not have to be the object returned by standardUserDefaults , I would be happy to create my own object. In case it matters: I'm especially interested in getting rid of the NSRegistrationDomain .
  • If the answer to the above is β€œno,” can we say that the five standard domains are simply β€œimmutable” and that all things in NSUserDefaults about adding / removing packages and persistent / mutable domains refer to user defined domains?
  • Is there a way to find out what is in the NSUserDefaults object's search list?

I suspect I already know the answers (no, yes and no), but at least I'm looking for someone who has more experience to confirm my suspicions.

+8
ios objective-c nsuserdefaults
source share
2 answers
  • To get rid of a domain such as NSRegistrationDomain , you must use removeVolatileDomainForName: However, this will not work with NSRegistrationDomain and NSArgumentDomain . These two cannot be deleted. Try registering your domain with setVolatileDomain:forName: You can delete this file.

    I believe that in the five standardUserDefaults domains, you can remove your own domain with removePersistentDomainForName: by passing the identifier of your package. But I have not tried this.

    Since NSGlobalDomain is persistent, and you can pass your own package identifier removePersistentDomainForName: I believe that you cannot remove NSGlobalDomain . Again, this is not verified.

  • I think so, with the exception of a permanent domain with your package ID.

  • No, but using -volatileDomainNames should be sufficient for most purposes.

+1
source share

try calling [myuserDefaults synchronize] right after your changes

0
source share

All Articles