使用 NSJSONSerialization 解析 JSON - 抛出 NSException
Posted
技术标签:
【中文标题】使用 NSJSONSerialization 解析 JSON - 抛出 NSException【英文标题】:Parsing JSON with NSJSONSerialization - NSException thrown 【发布时间】:2014-03-24 02:12:35 【问题描述】:我正在使用NSJSONSerialization
来解析从 php 页面下拉的 JSON。以下代码用于解析 JSON 并显示数据字段的值(首先包含 JSON 示例):
"status":200,"status_message":"Book Found","data":348
代码:
- (IBAction)btnClick:(id)sender
if(![_txtBox.text isEqual:@""])
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.mysite.comm/project/ws/name/%@",@"c"]]; //url for JSON
NSError *jsonError=nil;
NSString *jsonString = [self jsonStringWithUrl:url]; //get data as JSON
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; //convert to data
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error: &jsonError];
_txtView.text = (NSString *)[jsonObject objectForKey:@"data"];
但是,代码崩溃并且我收到以下错误消息。我怀疑它与这条线有关:_txtView.text = (NSString *)[jsonObject objectForKey:@"data"];
但我不确定要寻找什么。我是否试图以错误的方式从NSDictionary
获取数据?
2014-03-23 22:04:35.292 WebServiceTest[38975:60b] -[__NSCFNumber length]: unrecognized selector sent to instance 0x8d7f140
2014-03-23 22:04:35.296 WebServiceTest[38975:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x8d7f140'
*** First throw call stack:
(
0 CoreFoundation 0x017ec1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x0156b8e5 objc_exception_throw + 44
2 CoreFoundation 0x01889243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x017dc50b ___forwarding___ + 1019
4 CoreFoundation 0x017dc0ee _CF_forwarding_prep_0 + 14
5 Foundation 0x011894e4 -[NSConcreteAttributedString length] + 42
6 Foundation 0x01188a6c -[NSConcreteAttributedString initWithString:attributes:] + 182
7 UIKit 0x00939e9d -[UITextView setText:] + 125
8 WebServiceTest 0x00002922 -[WebServiceTestViewController btnClick:] + 610
9 libobjc.A.dylib 0x0157d880 -[NSObject performSelector:withObject:withObject:] + 77
10 UIKit 0x0022d3b9 -[UIApplication sendAction:to:from:forEvent:] + 108
11 UIKit 0x0022d345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
12 UIKit 0x0032ebd1 -[UIControl sendAction:to:forEvent:] + 66
13 UIKit 0x0032efc6 -[UIControl _sendActionsForEvents:withEvent:] + 577
14 UIKit 0x0032e243 -[UIControl touchesEnded:withEvent:] + 641
15 UIKit 0x0026cddd -[UIWindow _sendTouchesForEvent:] + 852
16 UIKit 0x0026d9d1 -[UIWindow sendEvent:] + 1117
17 UIKit 0x0023f5f2 -[UIApplication sendEvent:] + 242
18 UIKit 0x00229353 _UIApplicationHandleEventQueue + 11455
19 CoreFoundation 0x0177577f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
20 CoreFoundation 0x0177510b __CFRunLoopDoSources0 + 235
21 CoreFoundation 0x017921ae __CFRunLoopRun + 910
22 CoreFoundation 0x017919d3 CFRunLoopRunSpecific + 467
23 CoreFoundation 0x017917eb CFRunLoopRunInMode + 123
24 GraphicsServices 0x037e05ee GSEventRunModal + 192
25 GraphicsServices 0x037e042b GSEventRun + 104
26 UIKit 0x0022bf9b UIApplicationMain + 1225
27 WebServiceTest 0x000022fd main + 141
28 libdyld.dylib 0x01e33701 start + 1
29 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
【问题讨论】:
[__NSCFNumber length]: unrecognized selector sent to instance
-- 你有一个 NSNumber,你想把它当作一个 NSString。看来您的“数据”属性是一个 NSNumber。
实际上我确实在代码顶部包含了 JSON 作为注释。很抱歉造成混乱!
是的,我终于看到了。
【参考方案1】:
您显示的 JSON 对象将 348 列为整数值。因此,当NSJSONSerialization
得到它时,它会将其转换为 NSNumber。您需要在[jsonObject objectForKey:@"data"]
上调用-[NSNumber stringValue]
以将NSNumber
转换为NSString
。
【讨论】:
这解决了我的问题。但是,以下 JSON:"status":200,"status_message":"Book Found","data":"729"
给了我一个错误:'-[__NSCFString stringValue]: unrecognized selector sent to instance 0x1702286a0'
为什么要使用 __NSCFString
?
在这种情况下,“data”元素的值用引号括起来。这是一个字符串。如果您的 JSON 对象表现不佳,有时您会得到一个数字,有时是一个字符串,您可能希望将标签文本分配包裹在 if ( [[jsonObject objectForKey:@"data"] isKindOfClass:[NSString class]] ) else if ( [[jsonObject objectForKey:@"data"] isKindOfClass:[NSNumber class]] )
类型的构造周围,以确保您始终在正确的对象上调用正确的方法,具体取决于服务器/数据源为您提供的内容。
这就是我最终所做的。这有点奇怪,但它完成了工作。谢谢!以上是关于使用 NSJSONSerialization 解析 JSON - 抛出 NSException的主要内容,如果未能解决你的问题,请参考以下文章
如何使用来自 NSString 的 NSJSONSerialization 解析 Json [重复]
iOS - 在 Swift 中使用 NSJSONSerialization 解析 JSON 字典
NSJSONSerialization 无法解析有效的 JSON - “垃圾结束”