web-dev-qa-db-ja.com

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 "。コンパイラの警告からコードを守りたいと思っています。この警告を修正するにはどうすればよいですか?

85
Olly

以下を使用する必要があります。

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

の代わりに:

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

最初はNSStringオブジェクトへの定数ポインターであり、2番目は定数NSStringオブジェクトへのポインターです。

それは微妙な違いです。 setObject:forKey:が次のように宣言されているため、コンパイラの警告が発生します。

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

defaultName引数はNSString *型であることが期待されています。代わりに定数へのポインタを渡すと、別の何かが与えられます。

Update:これらの定数はstaticとして定義する必要があることを指摘したい単一のファイル内からのみ使用される場合。私はこの問題を自分で実行したため、これを言います:それらを静的として宣言しない場合、それらはグローバル名前空間に存在し、同じ名前の変数を別のファイルで使用することはできません。詳細については、 Objective-Cの定数 を参照してください。例で説明するために、これは1つの.mファイルでのみ使用する必要があるキーに現在使用しているものです。

static NSString * const kSomeLabel = @"...";
205
e.James

Objective-Cオブジェクトでconstを使用しないでください。実際に使用するように設計されていません。 NSStringオブジェクト(他の多くのオブジェクト)は、設計によりデフォルトですでに不変であるため、constにすることは無意味です。

e.James推奨 のように、NSString * constを使用できます。これは、NSStringへの定数ポインターです。これは、定数NSStringへのポインターであるconst NSString *NSString const *と同等)とは微妙に異なります。 NSString * constを使用すると、kPolyを新しいNSStringオブジェクトを指すように再割り当てできなくなります。

31
Adam Rosenfield

他のクラスからのアクセスの場合:

.h

extern NSString * const PolygonNumberOfSidesPrefsKey;

.m

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

現在のクラス内でのみアクセスする場合:

.m

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"
15
malhal

定数をよりわかりやすくすることをお勧めします。多角形の辺の数の定数は、どこからでも取得できます。提案として、どのように:

kDefaultsPolygonNumberOfSides;

代わりに。

5
Abizern

この問題に関する追加の背景については、Wikipediaに、ポインターを使用した定数構文について説明した優れた記事があります。 http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

3
Sean Murphy