将一个常量NSString用作NSUserDefaults的键

13 浏览
0 Comments

将一个常量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\"的警告。我很想让我的代码没有编译器警告。我该如何解决这个警告?

admin 更改状态以发布 2023年5月25日
0
0 Comments

不要在Objective-C对象中使用const,它们并不是为其设计的。由于其设计的缘故,NSString对象(以及其他许多对象)已经默认为不可变,因此使其成为const是没有用处的。

e.James提出,可以使用一个NSString * const,它是一个指向NSString的常量指针。这与const NSString *(相当于NSString const *)略有不同,后者是指向常量NSString的指针。使用NSString * const可以防止将kPoly重新分配为指向新的NSString对象。

0
0 Comments

你应该使用:

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 = @"...";

0