有没有办法在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"];
我能够访问此数据的唯一方法是首先将内部数组的内容设置为对象。想法?
答案 0 :(得分:60)
对于这样的嵌套键,您可以使用 keyPath 。 keyPath只是一系列用点连接的键。您可以使用它们从支持键值编码的对象中检索嵌套值 - 包括像您这样的NSDictionary对象。所以在你的情况下,这应该有效:
[result valueForKeyPath:@"location.name"];
有关键值编码的更多详细信息,请参阅Apple的Key-Value Coding Programming Guide。
答案 1 :(得分:1)
使用Simon Whitaker的正确答案,我能够通过在Dictionary中的Dictionary中嵌入Dictionary来构建常量层次结构。以下是从我的真实源代码修改的示例源代码。
这是一个现实世界的问题解决方案。在我的特定情况下,目标是组织字符串,以识别通过StoreKit在Apple的App Store for iOS中进行应用程序内购买的产品。想象一下,我们的应用程序提供了一对书中的内容,一本关于猫,另一本关于狗。此外,我们的应用程序销售内容的删节版本以及未删节内容。从简化升级到未删节意味着第三种产品“升级”。每本书都可能被翻译,在这种情况下是英语和意大利语。
看着我试图追踪的字符串,你可能会想“为什么那个人不只是使用字符串而不是通过这个KVC废话?”。好吧,注意第二个字符串,英语>猫>未删节。该字符串以附加的下划线结尾。那是因为当我使用iTunesConnect创建应用程序内购买产品时,我意外地将该项目创建为“耗材”而不是“非耗材”。 Apple即使您删除了该产品,也不允许更改ID。所以不能使用原始字符串;或者,我附加了下划线作为解决方法。所以重点是,这些字符串是任意和混乱的。
这种方法的另一个类似需求是,如果这些字符串值偶尔会在编译时发生变化,那么您不希望将复制粘贴到源代码中的多个位置。换句话说,常量的层次结构。
在Xcode中,我想要一种更好的方式来引用这些产品标识符。
// 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"
}
}
};
以下是访问这些三重嵌套词典的方法。
// 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"] );
答案 2 :(得分:0)
gfbPicture = [[[result objectForKey:@"metadata"] objectForKey:@"pictures"] objectForKey:@"picture"];