使用常量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