2009-04-15 13 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"