使用常量NSString作为NSUserDefaults的关键字

我正在使用NSUSerDefaults来存储用户的喜好。 我记得在某个地方把键设置为常量是一个好主意 – 我同意。 下面的代码是我目前拥有的:

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

我试图改变这个:

 @implementation Controller NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides"; -(void)savePolygonInfo { [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:polygon.numberOfSides] forKey:kPolygonNumberOfSides]; } 

虽然这个工作,它会产生“ warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type ”。 我热衷于保持我的代码免受编译器警告。 我怎样才能解决这个警告?

你应该使用:

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

代替:

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

第一个是一个指向NSString对象的常量指针,第二个是指向常量NSString对象的指针。

这是一个微妙的差异。 编译器警告发生,因为setObject:forKey:声明如下:

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

期望defaultName参数的types为NSString * 。 当你传递一个指向常量的指针时,你已经给了它不同的东西。

更新:我想指出,这些常量应该被定义为static如果他们只是从一个单一的文件中使用。 我这样说是因为我自己已经遇到了这个问题:如果你不声明它们是静态的,那么它们将存在于全局命名空间中,并且你将不能在另一个文件中使用具有相同名字的variables。 有关更多信息,请参阅Objective-C中的常量 。 通过例子来解释,这是我目前使用的密钥,我只需要在一个.m文件中使用:

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

不要对Objective-C对象使用const ,它们并不是真的被devise用来使用它。 NSString对象(等等)由于其devise已经默认是不可变的,所以使它们成为const是没有用的。

正如e.James所build议的 ,你可以使用一个NSString * const ,它是一个指向NSString的常量指针。 这与const NSString * (等价于NSString const * )是不同的,它是一个指向常量NSString的指针。 使用NSString * const可以防止您重新指派kPoly指向新的NSString对象。

从其他类访问:

。H

 extern NSString * const PolygonNumberOfSidesPrefsKey; 

.M

 NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey" 

只能在当前课程中访问:

.M

 static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey" 

我build议甚至使这个常量更具描述性。 多边形边数的常数可以来自任何地方。 作为一个build议,如何:

 kDefaultsPolygonNumberOfSides; 

代替。

关于这个问题的其他背景,维基百科上有一篇很好的文章,用指针解释常量语法: http : //en.wikipedia.org/wiki/Const_correctness#Pointers_and_references