Использование 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;
}
}