2009-04-15 15 views
79

我使用NSUSerDefaults来存储用户首选项。我记得在某处把键设置为常量是个好主意 - 我同意。下面的代码是我目前有:使用常量NSString作为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”。我热衷于保持我的代码免受编译器警告。我如何解决这个警告?

回答

195

应使用:的

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

代替:

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

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

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

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

它期待​​说法是NSString *类型。当你传递一个指向常量的指针时,你给了它不同的东西。

更新:我想指出的是,这些常量应该被定义为static,如果他们只打算从一个单一的文件中使用。我这样说是因为我自己遇到了这个问题:如果你没有声明它们是静态的,那么它们将存在于全局名称空间中,并且你将无法在另一个文件中使用具有相同名称的变量。有关更多信息,请参阅Constants in Objective-C。为了举例说明,这是我目前使用的,我只需要在一个.m文件中使用的密钥:

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

`NSString * const foo`的工作原理是因为`NSString`是不可变的,指针是不可变的,所以它永远不会改变正确吗?另外,我还记得C++中的`const`隐式是`static`(一个编译器优化),所以不需要调用它。这里也是如此吗? – Ternary 2015-12-21 17:02:39

28

不要使用const用Objective-C的对象,他们没有真正的设计使用它。 NSString对象(等等)由于其设计已经默认是不可改变的,所以使它们成为const是无用的。

作为e.James suggested,您可以使用NSString * const,这是一个指向NSString的常数指针。这与const NSString *(相当于NSString const *)略有不同,这是一个指向常数NSString的指针。使用NSString * const可以防止您重新指定kPoly指向新的NSString对象。

+0

关于使用const的好处。这就是为什么很多Objective-C类具有“可变”变体。 – 2009-04-15 21:45:33

5

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

kDefaultsPolygonNumberOfSides; 

改为。

14

对于来自其它类的访问:

.H

extern NSString * const PolygonNumberOfSidesPrefsKey; 

的.m

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey" 

仅对于当前类的内部的访问:

.M

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"