将一个常量NSString用作NSUserDefaults的键
将一个常量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
\"的警告。我很想让我的代码没有编译器警告。我该如何解决这个警告?
不要在Objective-C对象中使用const
,它们并不是为其设计的。由于其设计的缘故,NSString
对象(以及其他许多对象)已经默认为不可变,因此使其成为const
是没有用处的。
如e.James提出,可以使用一个NSString * const
,它是一个指向NSString
的常量指针。这与const NSString *
(相当于NSString const *
)略有不同,后者是指向常量NSString
的指针。使用NSString * const
可以防止将kPoly
重新分配为指向新的NSString
对象。
你应该使用:
NSString * const kPolygonNumberOfSides = @"..."; // const pointer
而不是:
NSString const * kPolygonNumberOfSides = @"..."; // pointer to const
两者之间有微妙的差别。编译器警告是因为 setObject:forKey:
被声明如下:
- (void)setObject:(id)value forKey:(NSString *)defaultName;
它期望 defaultName
参数的类型是 NSString *
。当你传递一个指向常量的指针时,你给了它不同的东西。
更新:我想指出,如果这些常量只在单个文件中使用,应该将它们定义为静态的。我之所以这样说是因为我自己也遇到过这个问题:如果不将它们声明为静态的,则它们会存在于全局命名空间中,你将无法在另一个文件中使用同名的变量。有关更多信息,请参见Constants in Objective-C。举个例子,这是我目前在一个.m
文件中仅需要使用一次的 key:
static NSString * const kSomeLabel = @"...";