Re: [問題] NSDictionary /NSArray /introspection

作者: uranusjr (←這人是超級笨蛋)   2014-06-04 15:39:56
※ 引述《sean72 (.)》之銘言:
: objective-C新手
: 送了一個URL request之後收到一個json回傳
: 使用了NSJSONSerialization將json轉換成NSDictionary
: 例如:
: rows = (
: {
: elements = (
: {
: distance = {
: text = "612 km";
: value = 611596;
: };
: duration = {
: text = "5 hours 47 mins";
: value = 20811;
: };
: status = OK;
: }
: );
: }
: );
: status = OK;
: }
: key是 @"rows"
: value是一包東西 我用isKindOfClass重複猜了兩三次
: 得知這個value是一個NSArry
: 問題一:
: 要怎麼快速得到某個物件是屬於哪個class?
: 我仍先預設這個物件也許是某種class我才能用isKindOfClass配上if驗證
: python裡面有個好功能 type(xxx)馬上可以回傳xxx的型別
[obj class] // 回傳 Class 物件
[obj className] // 回傳 NSString
其實你可以直接去查文件啊...
http://d.pr/uf0Z (developer.apple.com)
NSJSONSerialization 會用以下的表格對應 JSON types 與 Foundation types
JSON Foundation
============================
string NSString
number NSNumber
object NSDictionary (key 是 NSString)
array NSArray
true/false NSNumber
null NSNull
: 問題二
: 但是我要怎麼將這個NSArry的內容再次轉換成一個好用的Dictionary?
: 我最終的希望是能夠找到簡易的方式去取得
: distance.text="612km" / duration.text ="5 hours 47 mins"
: 謝謝大家幫忙
其實你可以直接把原始 JSON 在問題裡寫出來
我猜應該是類似這樣吧
{
"rows": [
{
"elements": [
{
"distance": {
"text": "612 km",
"value": 611596
},
"duration": {
"text": "5 hours 47 mins",
"value": 20811
},
"status": "OK"
}
]
}
]
}
那基本上就是
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
NSArray *elements = dict[@"rows"][0][@"elements"];
NSDictionary *element = elements[0];
NSDictionary *distance = element[@"distance"];
NSDictionary *duration = element[@"duration"];
NSLog(@"%@", distance[@"text"]);
NSLog(@"%@", duration[@"text"]);
如果要像你前面講的用 dot 就得為 distance 和 duration 建 class
這就自己發揮吧, 應該不難
=====
Edit:
有人講了 KVC, 其實這可以有, 如果你有很大的 dictionary 想轉成物件頗方便
用前面的例子以 distance 為例好了
@interface Distance : NSObject
- (id)initWithDictionary:(NSDictionary *)dict;
@property (nonatomic, strong) NSString *text;
@property (nonatomic, assign) NSInteger value; // 注意這裡
@end
@implementation Distance
- (id)init // 永遠 delegate 到 designated initializer 是好習慣
{
return [self initWithDictionary:@{}];
}
- (id)initWithDictionary:(NSDictionary *)dict
{
self = [super init];
if (!self)
return;
for (NSString *key in dict)
{
id value = dict[key];
if ([value isKindOfClass:[NSNull class]]) // 注意
value = nil;
[self setValue:value forKey:key];
}
}
@end
這邊要注意幾件事情
NSJSONSerialization 會用 NSNumber 表示 JSON 的 number type
但是這通常不是我們要的, 我們一般會希望使用 primary types
KVC 有自動轉換, 所以直接用 setValue:forKey: 就可以過
但是如果傳入的 NSNumber 物件是 nil, 結果就會是 0
這可能不是你想要的, 因為它和傳入 @0 的結果相同
所以可以依需求複寫 -setNilValueForKey: 來處理
當然如果你真的需要 NSNumber 也行
參照文件 http://d.pr/n/nd8f (Key-Value Coding Programming Guide)
另外因為 JSON 的 null 會對應到 NSNull
而它不能用在任何屬性上 (除非你的屬性就是 NSNull)
所以我們加了一個判斷, 把 NSNull instance 換成 nil
另外這篇完全是我手刻的
雖然不是 VIM, 不過其實大多數的 Objective-C method signatures 不難記
只是說說而已
作者: sean72 (.)   2014-06-04 17:07:00
非常感謝
作者: whitefur (白毛)   2014-06-04 22:23:00
推不難記 寫久了就記得了
作者: TsaoCCFGOGO (書唸累時,就算數學吧)   2014-06-05 00:22:00
推 寫久了就記得了

Links booklink

Contact Us: admin [ a t ] ucptt.com