views:

2232

answers:

4

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?

+10  A: 

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.

e.James
+5  A: 

Don't use const with Objective-C objects, they weren't really designed to use it. NSString objects (among many others) are already immutable by default by virtue of their design, so making them const is useless.

As e.James suggested, you can use an NSString * const, which is a constant pointer to an NSString. This is subtly different from a const NSString * (equivalent to NSString const *), which is a pointer to a constant NSString. Using a NSString * const prevents you from reassigning kPoly to point to a new NSString object.

Adam Rosenfield
Good point about the use of const. That's why a lot of Objective-C classes have "Mutable" variants.
e.James
+2  A: 

For additional background about this issue, there is an excellent article on Wikipedia explaining the constant syntax with pointers: http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

Sean Murphy
+1  A: 

I would suggest even making the constant more descriptive. A constant for the number of sides of a polygon could come from anywhere. As a suggestion, how about:

kDefaultsPolygonNumberOfSides;

instead.

Abizern