tags:

views:

2339

answers:

2

I'm using NSUserDefaults for a Settings Application. This is a pristine copy and I have not at all added anything to the filesystem for this particular setting. I expect it to be nil, but on the contrary..

If I do something like the following:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ( [defaults valueForKey:kIdentifierKey] == nil ) {
    return YES;
}
else {
    NSLog(@"we have a value. return NO. Value is: %@", [defaults objectForKey:kIdentifierKey]);
    return NO;
}

Yet in NSLog, nothing shows where you'd expect the value. The else block does indeed get executed. Is there any reason why this is NOT nil?

+5  A: 

valueForKey: is kind of a complex method in all the places it searches. I find it more reliable to use the getters for specific datatypes when dealing with defaults.

if ([defaults boolForKey:kIdentifierKey]) [self doSomething];

Or you could use objectForKey: which should return nil as you expect. In fact, you do this when you create your NSLog statement. And the string description of nil is @"" so your output is as you would expect.

Also, you are testing and logging different keys here:

[defaults valueForKey:kIdentifierKey];
[defaults objectForKey:kGroupIdentifierKey];

Making sure you are testing and logging what you think you are.


Test from a new iPhone project:

if (![[NSUserDefaults standardUserDefaults] valueForKey:@"foobar"])         NSLog(@"is not yet defined");
if (![[NSUserDefaults standardUserDefaults] objectForKey:@"foobar"])        NSLog(@"is not yet defined");
if ([[NSUserDefaults standardUserDefaults] valueForKey:@"foobar"] == nil)   NSLog(@"valueForKey is nil");
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"foobar"] == nil)  NSLog(@"objectForKey is nil");

It outputs:

is not yet defined
is not yet defined
valueForKey is nil
objectForKey is nil

I think you have something else going on here.

Squeegy
The identifier was just a typo. objectForKey: in this case is indeed not returning nil, unfortunately.
Coocoo4Cocoa
It does work the way you think it does. You seem to have another problem somewhere. see code snippet added to the bottom of my answerCheck to see if you have a [defaults registerDefaults:] methods being called that is seeding some data or something, like an empty string.
Squeegy
A: 

Based on the docs....

"A default’s value must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData. For more details, see User Defaults Programming Topics for Cocoa."

Also, [defaults valueForKey:] is not an instance method according to the documentation, so the result is most likely undefined. If you use [defaults objectForKey:] it will return nil if the object associated with kIdentifierKey is not found.

valueForKey: is an instance method of all NSObjects.
Chuck