Использование setValuesForKeysWithDictionary с дочерними объектами и JSON - PullRequest
8 голосов
/ 10 июня 2011

У меня есть строка 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 ]

7 голосов
/ 21 марта 2014

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

// Foo class

-(void)setBar:(id)bar
{
    if ([bar class] == [NSDictionary class]) {
        _bar = [Bar new];
        [_bar setValuesForKeysWithDictionary:bar];
    }
    else
    {
        _bar = bar;
    }
}
6 голосов
/ 10 июня 2011

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

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

...