Использование setValuesForKeysWithDictionary с дочерними объектами и JSON

У меня есть строка JSON

{"name":"test","bar":{"name":"testBar"}}

В цели c у меня есть объект

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

И я просто синтезирую эти свойства. И у меня есть дочерний объект с синтезированными свойствами.

@interface Bar : NSObject {
}
@property (nonatomic, retain) NSString * name;
@end

Тогда вот код, в котором я пытаюсь попасть в объект Foo, где response - это строка 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);

Это вызывает исключение в операторе NSLog:

-[__NSCFDictionary name]: unrecognized selector sent to instance 0x692ed70'

Но если я изменю код, он будет работать:

NSLog(@"bar name %@", [obj.bar valueForKey:@"name"]);

Я смущен, почему я не могу сделать первый пример, или я делаю что-то не так?

2 ответа

Решение

-setValuesForKeysWithDictionary: не достаточно умен, чтобы признать, что значение клавиши "бар" должно быть экземпляром Bar, Это назначение NSDictionary к этой собственности. Таким образом, когда вы запрашиваете свойство "имя", словарь не может выставить этот запрос. Тем не менее, NSDictionary знает, как справиться -valueForKey:, так бывает в таком случае.

Поэтому вам нужно использовать что-то умнее, чем -setValuesForKeysWithDictionary: заселить ваши объекты.

Вы пробовали это?

// Foo class

-(void)setBar:(id)bar
{
    if ([bar class] == [NSDictionary class]) {
        _bar = [Bar new];
        [_bar setValuesForKeysWithDictionary:bar];
    }
    else
    {
        _bar = bar;
    }
}
Другие вопросы по тегам