1
-(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 数据时发生错误。错误域 = NSCocoaErrorDomain 代码 = 3840 “操作无法完成。(可可错误 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 数据时发生错误。错误域 = NSCocoaErrorDomain 代码 = 3840 “操作无法完成。(可可错误 3840。)”(字符 0 周围的值无效。) UserInfo = 0x20888760 {NSDebugDescription = 字符 0 周围的值无效。}

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

4

1 回答 1

1

您应该首先在代码中修复这些问题:

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

    为了正确测试错误,您只需检查方法返回值。这些方法指示带有“特殊返回值”的错误条件。例如,它们返回或- 正如文档中始终指定的那样。只有在方法指示错误之后,提供的错误参数才会包含一个有意义的值——也就是说,它指向一个由该方法创建的对象。请注意,当方法成功时,此参数也可能变为 none NULL,在这种情况下,它没有“意义”。NOnilNSError

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

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

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

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

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

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

于 2013-06-20T11:14:24.193 回答