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