Mike S
Mike S

Reputation: 11409

NSUserDefaults setObject:nil vs. setNilValueForKey

My app crashes whenever I try the following line:

[[NSUserDefaults standardUserDefaults] setNilValueForKey:@"my_key"];

with this error: 'NSInvalidArgumentException', reason: '[<NSUserDefaults 0x7a2423d0> setNilValueForKey]: could not set nil as the value for the key my_key.'

But when I do this it seems to work:

[[NSUserDefaults standardUserDefaults] setObject:nil forKey:@"my_key"];

Can someone explain the difference between these 2 functions?

Upvotes: 3

Views: 4856

Answers (2)

Onik IV
Onik IV

Reputation: 5047

According to Apple doc : "The default implementation raises an NSInvalidArgumentException." Ovbiusly when you call it the NSInvalidArgumentException will be launched. You can call, but you will are launching an exception. Where use Apple this methods, well according to its doc. again: "Invoked by setValue:forKey: when it’s given a nil value for a scalar value (such as an int or float)."

Let's see a little example:

We create a new class, TestObject, we only add a couple of properties in its header (.h) file:

#import <Foundation/Foundation.h>

@interface TestObject : NSObject

@property (nonatomic, strong) NSString *keyString;
@property (nonatomic) int keyInteger;

@end

Well, now we import it in our viewController and we add the next code to the viewDidLoad methods in order to test:

    TestObject *testObject = [[TestObject alloc] init];
[testObject setValue:@"Hola" forKey:@"keyString"];
[testObject setValue:@2 forKey:@"keyInteger"];

@try {
    // This is the method wich launch the exception.
    [testObject setValue:nil forKey:@"keyInteger"];

    //  If you test this the exception won't be launched.
    //  [testObject setKeyInteger:nil];

}
@catch (NSException *exception) {
    NSLog(@"The exception name is %@",[exception name]);
}

NSLog(@"View values: %@\n%d",testObject.keyString,testObject.keyInteger);

Of course we can override this methods in our subclass, and change its behavior. All info: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/#//apple_ref/occ/instm/NSObject/setNilValueForKey:

Upvotes: 2

Jon Shier
Jon Shier

Reputation: 12770

setNilValueForKey: is part of the NSKeyValueCoding protocol and is not intended to be called directly, just overridden by classes with custom NSKeyValueCoding implementations. setObject:forKey:, however, is a method provided by NSUserDefaults and essentially removes the key from the defaults when sent with a nil object (though this behavior may look different in Swift).

Upvotes: 7

Related Questions