断开互联网连接时如何处理 NSJSONSerialization 崩溃

Posted

技术标签:

【中文标题】断开互联网连接时如何处理 NSJSONSerialization 崩溃【英文标题】:How to handle NSJSONSerialization's crashing when disconnected to internet 【发布时间】:2013-08-06 00:17:19 【问题描述】:

我在我的应用中实现了网络服务。我的方式很典型。

- (BOOL)application:(UIApplication *)application     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

//Web Service  xxx,yyy are not true data
    NSString *urlString =   @"http://xxx.byethost17.com/yyy";
    NSURL *url = [NSURL URLWithString:urlString];
    dispatch_async(kBackGroudQueue, ^
        NSData* data = [NSData dataWithContentsOfURL: url];
        [self performSelectorOnMainThread:@selector(receiveLatest:)     withObject:data waitUntilDone:YES];
    );   
    return YES;


- (void)receiveLatest:(NSData *)responseData 
    //parse out the json data
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                      JSONObjectWithData:responseData
                      options:kNilOptions
                      error:&error];
    NSString *Draw_539 = [json objectForKey:@"Draw_539"];
....

控制台错误信息:

* 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'数据参数为零'

当我的 iphone 连接到 Internet 时,该应用程序可以成功运行。但是如果它与 Internet 断开连接,应用程序将在 NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 上崩溃 你能告诉我如何处理这个错误吗? NSError 有用吗?

【问题讨论】:

错误告诉你“responseData”为nil。避免异常的方法是测试“responseData”,如果它为 nil,则不调用 JSONObjectWithData。相反,您应该对这种错误情况做出反应。 try/catch,或者看看error是不是错误。 @HotLicks 谢谢,我添加了 if 语句 if(responseData)。那么当 responseData 为 nil 时, JSONObjectWithData 将不会被调用。我认为我的问题是常见的和入门级的,但我在网络上找不到信息。 你缺乏的是阅读错误信息的技能——花一点时间/精力来改进那里。错误消息告诉您“数据参数为零”,这显然是指 JSONObjectWithData 的参数。如果传输时互联网连接失败,这在逻辑上将为零。如果你想成为一名程序员,这就是你需要学习如何弄清楚的事情。 @HotLicks 现在我的问题已经解决了,但是下面没有人“回答我的问题”。 【参考方案1】:

错误告诉您“responseData”为 nil。避免异常的方法是测试“responseData”,如果它为 nil,则不调用 JSONObjectWithData。相反,您应该对这种错误情况做出反应。

【讨论】:

关于如何优雅地检查“responseData”是否为 nil 的任何建议?【参考方案2】:

在将responseData 传递给JSONObjectWithData:options:error: 方法之前,您没有检查您的responseData 是否为nil。

也许你应该试试这个:

- (void)receiveLatest:(NSData *)responseData 
    //parse out the json data
    NSError* error;
    if(responseData != nil)
    
         NSDictionary* json = [NSJSONSerialization
                      JSONObjectWithData:responseData
                      options:kNilOptions
                      error:&error];
         NSString *Draw_539 = [json objectForKey:@"Draw_539"];
    
    else
    
         //Handle error or alert user here
    
    ....

EDIT-1:为了良好的实践,你应该在JSONObjectWithData:options:error:方法之后检查这个error对象来检查JSON数据是否成功转换为NSDictionary

- (void)receiveLatest:(NSData *)responseData 
    //parse out the json data
    NSError* error;
    if(responseData != nil)
    
         NSDictionary* json = [NSJSONSerialization
                      JSONObjectWithData:responseData
                      options:kNilOptions
                      error:&error];
         if(!error)
         
              NSString *Draw_539 = [json objectForKey:@"Draw_539"];
         
         else
         
              NSLog(@"Error: %@", [error localizedDescription]);
              //Do additional data manipulation or handling work here.
          
    
    else
    
         //Handle error or alert user here
    
    ....

【讨论】:

以上是关于断开互联网连接时如何处理 NSJSONSerialization 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 Symfony 时如何处理连接表中的附加列?

连接停止时如何处理猫鼬数据库

使用 ActiveMerchant 时如何处理超时?

如何处理与 python 套接字的断开连接? (连接重置错误)

访问从不同线程访问的控件时如何处理无效的跨线程操作?

应用关闭时如何处理 UNNotificationAction?