0

valueForKey: や intForKey:、stringForKey: などがあるのはなぜですか。

しかし、valueForKeyPath: があり、intForKeyPath:、stringForKeyPath: などはありませんか?

4

2 に答える 2

1

Appleは、 またはNSDictionaryという名前のメッセージをサポートしていません。intForKey:stringForKey:

これらのメッセージをカテゴリに追加するサードパーティ ライブラリを使用している可能性があります。そのライブラリの作成者に、メッセージのキーパス バージョンを含めなかった理由を尋ねることができます。

おそらく、あなたはNSUserDefaultsではなくを考えているでしょうNSDictionaryNSUserDefaults了解integerForKey:ですstringForKey:NSUserDefaults大規模で複雑な構造を保存するためのものではありません。小さくて単純なデータを格納することを目的としています。

于 2012-12-21T04:36:58.850 に答える
0

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、オブジェクト タイプの検証です。NSArrayof をNSDictionarykey の下に保存していて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:のプリミティブ型ではなく、オブジェクトを返す必要があることです。実際、オブジェクトに のようなプリミティブ型のプロパティがある場合、 を呼び出すと自動的にラップされて が返されます。このため、拡張アクセサーを使用してもあまり意味がありません。intfloatheightNSInteger[object valueForKeyPath:@"height"]NSNumber*ForKeyPath:

于 2012-12-21T05:05:58.013 に答える