我有这个代码Json格式:
{
"weather": [{
"description": "clear sky",
"icon": "01n"
}],
"base": "stations",
"main": {
"temp": 285.514
},
"clouds": {
"all": 0
},
"dt": 1485792967,
"id": 1907296
}
我想要检索图标字符串(01n)
并使用此代码:
@property(nonatomic,strong) NSString *cityImageName;
self.cityImageName = [[dataJson valueForKey:@"weather"] valueForKey:@"icon"];
后来当我检查变量打印时:
<__NSSingleObjectArrayI 0x604000009890>(
01n
)
最后如何直接获取字符串?不像__NSSingleObjectArrayI
答案 0 :(得分:10)
您遇到了键值编码陷阱。
valueForKey
有一种特殊行为。应用于数组时,它始终返回给定键的所有值的数组。
除非您打算使用KVC,否则永远不要使用valueForKey
。建议的语法是objectForKey
或 - 首选 - 密钥订阅以及数组索引订阅。
在这种情况下,您希望获取键icon
数组中第一项的键weather
的值。
self.cityImageName = dataJson[@"weather"][0][@"icon"];
但是,如果数组不为空,我会添加一个检查,以避免超出范围的异常
NSArray *weather = dataJson[@"weather"];
if (weather && weather.count > 0) {
self.cityImageName = weather[0][@"icon"];
}
答案 1 :(得分:4)
__NSSingleObjectArrayI
是NSArray
class cluster的其中一个实现。除了知道它是一个数组之外,这个问题并不重要。
你得到一个数组(一个元素)而不是一个字符串的原因是因为你正在使用的JSON包含一个数组,里面有一个字典:
"weather": [{
"description": "clear sky",
"icon": "01n"
}],
注意:大括号周围的方括号。
所以,当你调用[dataJson valueForKey:@"weather"]
时,你会找回代表JSON这一部分的对象:
[ { "description": "clear sky", "icon": "01n" } ]
在这种情况下,已将其解码为NSArray
,其中包含一个带有两个密钥的NSDictionary
。
然后再拨打valueForKey:
on that array
返回一个数组,其中包含在每个数组对象上使用
valueForKey:
调用key
的结果。
换句话说,因为[dataJson valueForKey:@"weather"]
是一个字典的数组,[[dataJson valueForKey:@"weather"] valueForKey:@"icon"]
是一个只包含该字典中"icon"
键值的数组。
如果您使用的JSON始终具有此格式,那么您可以从数组中获取firstObject
以获取第一个字符串(如果数组为空,则为nil
)