Using a constant NSString as the key for NSUserDefaults

Olly picture Olly · Apr 15, 2009 · Viewed 49.3k times · Source

I'm using NSUSerDefaults to store user preferences. I remember reading somewhere that setting the keys as constants is a good idea - and I agree. The following code is what I currently have:

[[NSUserDefaults standardUserDefaults]
        setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
           forKey:@"polygonNumberOfSides"];

I tried changing this to:

@implementation Controller

NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides";

-(void)savePolygonInfo {
    [[NSUserDefaults standardUserDefaults]
            setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
               forKey:kPolygonNumberOfSides];
}

While this does work, it produces "warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type". I'm keen to keep my code free from compiler warnings. How can I fix this warning?

Answer

e.James picture e.James · Apr 15, 2009

You should use:

NSString * const kPolygonNumberOfSides = @"..."; // const pointer

instead of:

NSString const * kPolygonNumberOfSides = @"..."; // pointer to const

The first is a constant pointer to an NSString object, while the second is a pointer to a constant NSString object.

It is a subtle difference. The compiler warning happens because setObject:forKey: is declared as follows:

- (void)setObject:(id)value forKey:(NSString *)defaultName;

It is expecting the defaultName argument to be of type NSString *. When you instead pass in a pointer to a constant, you've given it something different.

Update: I want to point out that these constants should be defined as static if they are only going to be used from within a single file. I say this because I have run across this problem myself: if you do not declare them as static, then they will exist in the global namespace, and you will not be able to use a variable with the same the same name in another file. see Constants in Objective-C for more information. To explain by example, this is what I currently use for keys that I only need to use in one .m file:

static NSString * const kSomeLabel = @"...";