2011-06-09 49 views
8

我有一個JSON字符串與子對象使用setValuesForKeysWithDictionary和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 

那麼這裏就是我試圖進入美孚對象,其中響應上面的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"]); 

我很困惑,爲什麼我不能做第一個例子,或者我做錯了什麼?

回答

6

-setValuesForKeysWithDictionary:不夠智能地認識到鍵「bar」的值應該是Bar的一個實例。它將該物業分配給NSDictionary。因此,當你要求財產「名稱」時,字典不能提出該請求。然而,NSDictionary確實知道如何處理-valueForKey:,所以恰巧在這種情況下工作。

所以你需要使用比-setValuesForKeysWithDictionary:更聰明的東西來填充你的對象。

+1

「的東西更聰明,」 像......? – 2012-02-09 04:10:15

+0

沒有內置的解決方案,但編寫一個並不困難。假設你的對象屬性沒有初始化爲'nil',你可以編寫一個'-setValuesForKeysWithDictionary:'的簡單遞歸替換。它會爲字典中的每個值調用'setValue:forKey:',除非該值本身就是一個字典。在這一點上,你可以用'valueForKey:'的結果和剛剛找到的字典遞歸地調用你的函數。 – 2012-02-09 07:06:23

+0

好的。不知道是否有本地認可的方式。這就是我所設想的。也許我甚至可以將這樣的功能放到某個基類中,以便在給出字典時解析它並填充它自己。 – 2012-02-09 16:19:50

7

你試過嗎?

// Foo class

-(void)setBar:(id)bar 
{ 
    if ([bar class] == [NSDictionary class]) { 
     _bar = [Bar new]; 
     [_bar setValuesForKeysWithDictionary:bar]; 
    } 
    else 
    { 
     _bar = bar; 
    } 
} 
+1

它應該是:if([bar isKindOfClass:[NSDictionary class]]) – magofdl 2016-04-21 23:12:30