使用valueForKeyPath获取数组元素

jsd*_*jsd 20 cocoa objective-c key-value-coding

有没有办法访问NSArray元素valueForKeyPath?例如,Google的反向地理编码器服务会返回一个非常复杂的数据结构.如果我想要进入这个城市,那么现在我必须把它分成两个电话,像这样:

NSDictionary *address = [NSString stringWithString:[[[dictionary objectForKey:@"Placemark"] objectAtIndex:0] objectForKey:@"address"]];
NSLog(@"%@", [address valueForKeyPath:@"AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName"]);
Run Code Online (Sandbox Code Playgroud)

只是想知道是否有办法将objectAtIndex:调用塞入valueForKeyPath字符串.我尝试了像@"Placemark [0] .address"这样的javascript-esque配方,但没有骰子.

Ale*_*lex 18

很不幸的是,不行.此处提供了使用键值编码所允许内容的完整文档.据我所知,没有任何允许您获取特定数组或设置对象的运算符.

  • 请更新此答案中的链接,页面不再存在. (2认同)

psy*_*psy 16

这是我刚刚为NSObject编写的一个类,它可以处理数组索引,因此你可以像这样访问一个嵌套对象:"person.friends [0] .name"

@interface NSObject (ValueForKeyPathWithIndexes)
   -(id)valueForKeyPathWithIndexes:(NSString*)fullPath;
@end


#import "NSObject+ValueForKeyPathWithIndexes.h"    
@implementation NSObject (ValueForKeyPathWithIndexes)

-(id)valueForKeyPathWithIndexes:(NSString*)fullPath
{
    NSRange testrange = [fullPath rangeOfString:@"["];
    if (testrange.location == NSNotFound)
        return [self valueForKeyPath:fullPath];

    NSArray* parts = [fullPath componentsSeparatedByString:@"."];
    id currentObj = self;
    for (NSString* part in parts)
    {
        NSRange range1 = [part rangeOfString:@"["];
        if (range1.location == NSNotFound)          
        {
            currentObj = [currentObj valueForKey:part];
        }
        else
        {
            NSString* arrayKey = [part substringToIndex:range1.location];
            int index = [[[part substringToIndex:part.length-1] substringFromIndex:range1.location+1] intValue];
            currentObj = [[currentObj valueForKey:arrayKey] objectAtIndex:index];
        }
    }
    return currentObj;
}
@end
Run Code Online (Sandbox Code Playgroud)

像这样使用它

NSString* personsFriendsName = [obj valueForKeyPathsWithIndexes:@"me.friends[0].name"];
Run Code Online (Sandbox Code Playgroud)

没有错误检查,所以它很容易破坏,但你明白了.

  • 现在我们有了改进的Obj-C文字语法,这种无关紧要.您可以在我的问题中将原始语句写成`NSDictionary*address = dictionary [@"Placemark"] [0] [@"address"];` (4认同)
  • 是的新语法很棒.我在上面的示例中使用了外部数据结构可能发生变化的情况,因此字符串选择器非常有用. (2认同)