使用常量NSString作为NSUserDefaults的键

问题描述 投票:85回答:5

我正在使用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 cocoa default-value
5个回答
207
投票

您应使用:

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

而不是:

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

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

这是微妙的区别。发生编译器警告是因为setObject:forKey:声明如下:

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

期望defaultName参数为NSString *类型。相反,当您传递指向常量的指针时,您给了它不同的东西。

[Update:我想指出,如果仅在单个文件中使用这些常量,则应将其定义为static。我之所以这样说,是因为我自己遇到了这个问题:如果您不将它们声明为静态,则它们将存在于全局名称空间中,并且您将无法在另一个文件中使用具有相同名称的变量。有关更多信息,请参见Constants in Objective-C。为了举例说明,这是我目前用于只需要在一个.m文件中使用的键的内容:

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

32
投票

不要将const与Objective-C对象一起使用,它们并不是真正为使用它而设计的。默认情况下,NSString对象(还有许多其他对象)由于其设计已经是不可变的,因此使它们成为const是没有用的。

作为e.James suggested,您可以使用NSString * const,它是指向NSString的常量指针。这与const NSString *(等效于NSString const *)略有不同,后者是指向常量NSString的指针。使用NSString * const可以防止您重新分配kPoly指向新的NSString对象。


17
投票

用于从其他类进行访问:

。h

extern NSString * const PolygonNumberOfSidesPrefsKey;

。m

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSides"

仅用于在当前类内部访问:

。m

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSides"

5
投票

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

kDefaultsPolygonNumberOfSides;

代替。


3
投票

有关此问题的其他背景,Wikipedia上有一篇很好的文章,解释了带有指针的常量语法:http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

© www.soinside.com 2019 - 2024. All rights reserved.