valueForKey: や intForKey:、stringForKey: などがあるのはなぜですか。
しかし、valueForKeyPath: があり、intForKeyPath:、stringForKeyPath: などはありませんか?
valueForKey: や intForKey:、stringForKey: などがあるのはなぜですか。
しかし、valueForKeyPath: があり、intForKeyPath:、stringForKeyPath: などはありませんか?
Appleは、 またはNSDictionary
という名前のメッセージをサポートしていません。intForKey:
stringForKey:
これらのメッセージをカテゴリに追加するサードパーティ ライブラリを使用している可能性があります。そのライブラリの作成者に、メッセージのキーパス バージョンを含めなかった理由を尋ねることができます。
おそらく、あなたはNSUserDefaults
ではなくを考えているでしょうNSDictionary
。 NSUserDefaults
了解integerForKey:
ですstringForKey:
。 NSUserDefaults
大規模で複雑な構造を保存するためのものではありません。小さくて単純なデータを格納することを目的としています。
2 つの異なるオブジェクト (実際には、1 つのオブジェクトと 1 つの非公式プロトコル) のメソッド名と非公式プロトコルを混在させていNSUserDefaults
ますNSKeyValueCoding
。
NSUserDefaults
キー値のコーディングとキー値の監視は、OS X 10.3 以降でのみ使用されています。
NSUserDefaults
アプリの起動間の永続性のために、プロパティ リスト互換オブジェクト (NSData、NSDate、NSString、NSArray、および NSDictionary) の保存を扱います。多くの場合、アプリは BOOL や int などの非オブジェクト型の値を格納する必要がありますが、オブジェクトのみがサポートされているため、これらの便利なメソッド ( intForKey:
、boolForKey:
など) を使用すると、より簡潔な方法でそれらを保存できます。たとえば、次のコード行
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:MDFirstLaunchKey];
になります:
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:MDFirstLaunchKey];
対応する「get」メソッドを使用すると、より簡潔なコードで非オブジェクト型の値を取得できます。
これらのメソッドのもう 1 つの目的はNSUserDefaults
、オブジェクト タイプの検証です。NSArray
of をNSDictionary
key の下に保存していてMDClientsKey
、誤って次のコードを書いたとします。
NSDictionary *client = [userDefaults objectForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];
Objective-C の動的な性質は、そのobjectForKey:
呼び出しに対してユーザーの既定値が返すオブジェクトがNSDictionary
、コードが想定する ではなく、 であることを意味しNSArray
ます。後続の行objectForKey:
で NSArray を呼び出そうとすると、NSInvalidArgumentException が発生し、アプリがクラッシュする可能性があります。
代わりに を使用していた場合はdictionaryForKey:
、次のNSUserDefaults
ように返されnil
ます。
NSDictionary *client = [userDefaults dictionaryForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];
後続の行は、メッセージを に送信したことを意味しますがnil
、これは単に無視されます (つまり、クラッシュはありません)。
一方、メソッドvalueForKey:
とvalueForKeyPath:
メソッドはNSKeyValueCoding
非公式プロトコルの一部です。NSString
基本的に、メソッドを呼び出すのではなく、を使用して、あるオブジェクトが別のインスタンス変数に名前でアクセスできるようにします。これの重要な部分は、valueForKey:
やなどvalueForKeyPath:
のプリミティブ型ではなく、オブジェクトを返す必要があることです。実際、オブジェクトに のようなプリミティブ型のプロパティがある場合、 を呼び出すと自動的にラップされて が返されます。このため、拡張アクセサーを使用してもあまり意味がありません。int
float
height
NSInteger
[object valueForKeyPath:@"height"]
NSNumber
*ForKeyPath: