25

Objective-Cで外部配列の内部配列に直接アクセスする方法はありますか? たとえば、外部データ ソースを呼び出すと、次のオブジェクトが返されます。

{
bio = "this is the profile.bio data";
"first_name" = John;
"last_name" = Doe;
location =     {
    name = "Any Town, Any State";
};
metadata =    {
    pictures =    {
        picture = "https://picture.mysite.com/picture.jpeg";
    }
}
}

たとえば、location.name または metadata.pictures.picture データにアクセスできるようにしたいと考えています。ただし、ドット表記は機能しないようです。例えば:

_gfbLocation = [result objectForKey:@"location.name"];
_gfbPicture = [result objectForKey:@"metadata.pictures.picture"];

このデータにアクセスできる唯一の方法は、最初に内部配列の内容をオブジェクトに設定することです。考え?

4

3 に答える 3

62

そのようなネストされたキーの場合、keyPathを使用できます。keyPath は、ドットで結合された一連のキーです。それらを使用して、Key-Value Coding をサポートするオブジェクト (あなたのような NSDictionary オブジェクトを含む) からネストされた値を取得できます。したがって、あなたの場合、これはうまくいくはずです:

[result valueForKeyPath:@"location.name"];

Key-Value Coding の詳細については、Apple のKey-Value Coding Programming Guideを参照してください。

この関連する StackOverflow questionも参照してください。

于 2010-11-30T19:50:13.233 に答える
1

Simon Whitaker の正解を使用して、Dictionary を Dictionary 内の Dictionary に埋め込むことで、定数の階層を構築することができました。以下は、実際のソース コードを変更したソース コードの例です。

これは現実世界の問題解決です。私の特定のケースでは、Apple の App Store for iOS での In-App Purchase のために StoreKit 経由でアクセスされる製品を識別する文字列を整理することが目標でした。私たちのアプリが 2 冊の本 (1 つは猫、もう 1 つは犬) のコンテンツを表示するとします。さらに、私たちのアプリは、要約されていないコンテンツだけでなく、要約されたバージョンも販売しています。要約から非要約へのアップグレードは、第 3 の製品である「アップグレード」を意味します。本の各ペアが翻訳される場合があります。この場合、英語とイタリア語です。

私が追跡しようとしている文字列を見ると、「なぜあの男は、この KVC ナンセンスを経験するのではなく、文字列自体を使用しないのですか?」と思うかもしれません。さて、2 番目の文字列、English > Cats > Unabridged に注目してください。文字列は、追加されたアンダースコアで終わります。これは、iTunesConnect を使用してアプリ内購入製品を作成したときに、誤ってその項目を「非消耗品」ではなく「消耗品」として作成したためです。当該製品を削除しても、Apple は ID を変更することを許可しません。そのため、元の文字列は使用できませんでした。または、回避策としてアンダースコアを追加しました。つまり、これらの文字列は恣意的で乱雑です。

このアプローチの別の同様の必要性は、これらの文字列値がコンパイル時に時々変更される可能性があるため、ソースコードの複数の場所にコピーアンドペーストしたくない場合です。言い換えれば、定数の階層です。

Xcode 内で、これらの製品 ID を参照するより良い方法が必要です。

// Using new literals syntax in later versions of Xcode 4 (& 5) to declare and populate a dictionary nested in a dictionary also in a dictionary.
NSDictionary *productIdentifiersHierarchy = @{
                                              @"en" : @{
                                                      @"cats" : @{
                                                              @"abridged" : @"com.example.My_App.cats_abridged_en",
                                                              @"unabridged" : @"com.example.My_App.cats_unabridged_en_",
                                                              @"upgrade" : @"com.example.My_App.cats_upgrade_en"
                                                              },
                                                      @"dogs" :  @{
                                                              @"abridged" : @"com.example.My_App.dogs_abridged_en",
                                                              @"unabridged" : @"com.example.My_App.dogs_unabridged_en",
                                                              @"upgrade" : @"com.example.My_App.dogs_upgrade_en"
                                                              }
                                                      },
                                              @"it" : @{
                                                      @"cats" : @{
                                                              @"abridged" : @"com.example.My_App.cats_abridged_it",
                                                              @"unabridged" : @"com.example.My_App.cats_unabridged_it",
                                                              @"upgrade" : @"com.example.My_App.cats_upgrade_it"
                                                              },
                                                      @"dogs" :  @{
                                                              @"abridged" : @"com.example.My_App.dogs_abridged_it",
                                                              @"unabridged" : @"com.example.My_App.dogs_unabridged_it",
                                                              @"upgrade" : @"com.example.My_App.dogs_upgrade_it"
                                                              }
                                                      }
                                              };

これらの 3 重ネストされた辞書にアクセスする方法は次のとおりです。

// Use KVC (Key-Value Coding) as a convenient way to access the nested dictionary structure.
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.abridged"] );
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.unabridged"] );
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.upgrade"] );
于 2013-11-16T06:04:48.607 に答える
0
gfbPicture = [[[result objectForKey:@"metadata"] objectForKey:@"pictures"] objectForKey:@"picture"];
于 2010-11-30T19:42:44.897 に答える