【问题标题】:ERROR happened while deserializing the JSON data反序列化 JSON 数据时发生错误
【发布时间】:2013-06-16 23:25:57
【问题描述】:
-(void) conn:(NSString *)method{

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
    __block NSDictionary *resultBlock = nil;
    dispatch_sync(concurrentQueue, ^{
        /* Download the json here */

        //Create webservice address
        NSString *webService = [_baseURL stringByAppendingString:_webService];
        //NSLog(@"%@", webService);
        //Create error object
        NSError *downloadError = nil;

        //Create the request
        NSMutableURLRequest *req = [self initRequest:webService method:method];

        if(req != nil){
            //Request the json data from the server
            NSData *jsonData = [NSURLConnection
                                    sendSynchronousRequest:req
                                    returningResponse:nil
                                    error:&downloadError];

            if(downloadError!=nil){
                NSLog(@"DOWNLOAD ERROR %@", downloadError);
            }

            NSError *error = nil;
            id jsonObject = nil;

            if(jsonData !=nil){

                /* Now try to deserialize the JSON object into a dictionary */
                jsonObject = [NSJSONSerialization
                                 JSONObjectWithData:jsonData
                                 options:kNilOptions
                                 error: &error];
            }


            //Handel the deserialized object data
            if (jsonObject != nil && error == nil){
                NSLog(@"Successfully deserialized...");
                if ([jsonObject isKindOfClass:[NSDictionary class]]){
                    resultBlock = (NSDictionary *)jsonObject;
                    //NSLog(@"Deserialized JSON Dictionary = %@", resultBlock);
                }
                else if ([jsonObject isKindOfClass:[NSArray class]]){
                    NSArray *deserializedArray = (NSArray *)jsonObject;
                    NSLog(@"Deserialized JSON Array = %@", deserializedArray);
                } else {
                    /* Some other object was returned. We don't know how to deal
                     with this situation, as the deserializer returns only dictionaries
                     or arrays */
                }
            }
            else if (error != nil){
                NSLog(@"An error happened while deserializing the JSON data. %@", error);
            }else{
                NSLog(@"No data could get downloaded from the URL.");
                //[self conn:method];
            }
        }
    });
    dispatch_sync(dispatch_get_main_queue(), ^{

        /* Check if the resultBlock is not nil*/
        if(resultBlock != nil){
            /*Set the value of result. This will notify the observer*/
            [self setResult:resultBlock];
        }
    });
});
}

为什么会出现以下错误?

反序列化 JSON 数据时出错。错误 Domain=NSCocoaErrorDomain Code=3840 "无法执行该操作 完全的。 (Cocoa 错误 3840。)”(JSON 文本不是以数组开头或 允许未设置片段的对象和选项。) UserInfo=0x20839f80 {NSDebugDescription=JSON 文本不是以数组或对象开头并且 允许未设置片段的选项。}

当我把它改成

  /* Now try to deserialize the JSON object into a dictionary */
                jsonObject = [NSJSONSerialization
                                 JSONObjectWithData:jsonData
                                 options:NSJSONReadingAllowFragments
                                 error: &error];
            }

我收到以下错误:

反序列化 JSON 数据时出错。错误 Domain=NSCocoaErrorDomain Code=3840 "无法执行该操作 完全的。 (Cocoa 错误 3840。)”(字符 0 周围的值无效。) UserInfo=0x20888760 {NSDebugDescription=字符周围的值无效 0.}

我将连接从 LTE 更改为 wifi,现在我得到了 504 错误和 NSLog(@"无法从 URL 下载数据。");

【问题讨论】:

  • 看来你的JSON是无效的,你可以使用在线工具来验证它例如this one
  • 我验证了json,很好
  • 你能在其他 JSON 上测试你的代码吗?
  • 我已经写了一个 JSON 解析器。我只需要尝试将 JSON 对象反序列化为字典,但我收到 504 错误,这意味着服务器可能有问题。
  • 虽然我这样做很麻烦,但我必须给你 +1 以实际检查错误值。

标签: objective-c json nsjsonserialization


【解决方案1】:

您应该首先在您的代码中解决这些问题:

  1. 正确检查提供指向 NSError 对象的引用作为最后一个参数的方法中的错误,例如:- (BOOL) doSomething:(NSError**)error-(NSData*) doSomething:(NSError**)error

    为了正确测试错误,您必须检查方法的返回值only。这些方法指示带有“特殊返回值”的错误条件。例如,它们返回NOnil - 正如文档中指定的始终。只有在方法指示错误之后,提供的 error 参数才包含一个有意义的值——即,它指向该方法创建的NSError 对象。注意,这个参数也可能在方法成功的时候变成none NULL,这种情况下没有“意义”。

  2. Web 服务通常可以提供多种格式的请求资源。如果您不指定希望服务器对资源进行编码的格式,您将获得默认格式 - 不是一定是 JSON。

    为了明确说明所需的资源格式,请设置相应的“Accept”标头。例如,如果您希望采用 JSON 格式,您可以在请求中设置标头:"Accept: application/json"

  3. Web 服务可能有理由不响应您请求的资源。为了确保您收到了请求的响应,您需要检查响应中的状态代码和 MIME 类型,以确保您实际上收到了 JSON 响应。

  4. 您似乎有点不确定如何使用调度函数来发挥自己的优势。如果你使用同步方便的方法sendSynchronousRequest:...你当然只需要将它包装在一个dispatch_async函数中。如果你想在主线程上设置结果,你当然想使用dispatch_async,而不是dispatch_sync。

    但是,如果您改用sendAsynchronousRequest:...,那将是一种改进。只有当你在异步模式下使用NSURLConnection 并实现NSURLConnection 委托方法——我强烈推荐——它实际上会变得很棒;)

所以,我认为,一旦你修复了你的代码,你就可以自己回答原始问题,或者从服务器获得更好的错误响应,或者错误神奇地消失了;)

【讨论】:

  • 我今天早上尝试了代码,一切正常。代理或网关没有快速响应,但现在可以及时响应。
  • 太棒了! :) 尽管如此,你应该解决这些问题。他们迟早会咬你的;)
猜你喜欢
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
相关资源
最近更新 更多