将setValuesForKeysWithDictionary与子对象和JSON一起使用

Tav*_*nes 8 objective-c key-value-coding

我有一个json字符串

{"name":"test","bar":{"name":"testBar"}}
Run Code Online (Sandbox Code Playgroud)

在目标c中我有一个对象

@interface Foo : NSObject {
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Bar * bar;
@end
Run Code Online (Sandbox Code Playgroud)

我只是综合了这些属性.我有一个具有综合属性的子对象.

@interface Bar : NSObject {
}
@property (nonatomic, retain) NSString * name;
@end
Run Code Online (Sandbox Code Playgroud)

然后这里是我试图进入Foo对象的代码,其中响应是上面的json字符串:

    SBJsonParser *json = [[SBJsonParser new] autorelease];
    parsedResponse = [json objectWithString:response error:&error];
    Foo * obj = [[Foo new] autorelease];
    [obj setValuesForKeysWithDictionary:parsedResponse];
    NSLog(@"bar name %@", obj.bar.name);
Run Code Online (Sandbox Code Playgroud)

这会在NSLog语句中引发异常:

-[__NSCFDictionary name]: unrecognized selector sent to instance 0x692ed70'
Run Code Online (Sandbox Code Playgroud)

但是,如果我将代码更改为它的工作原理:

NSLog(@"bar name %@", [obj.bar valueForKey:@"name"]);
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么我不能做第一个例子,或者我做错了什么?

小智 7

你试过这个吗?

// Foo class

-(void)setBar:(id)bar
{
    if ([bar class] == [NSDictionary class]) {
        _bar = [Bar new];
        [_bar setValuesForKeysWithDictionary:bar];
    }
    else
    {
        _bar = bar;
    }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*eek 6

-setValuesForKeysWithDictionary:不够聪明,不能认识到键"bar"的值应该是一个实例Bar.它正在NSDictionary为该属性分配一个.因此,当您要求属性"name"时,字典无法表示该请求.但是,NSDictionary确实知道如何处理-valueForKey:,所以它恰好在这种情况下工作.

所以你需要使用比-setValuesForKeysWithDictionary:填充对象更聪明的东西.