8

看来我还没有完全理解块的概念......

在我的代码中,我必须从 ' ' 方法中取出asychronous block要返回的 JSON 数据。outer我用谷歌搜索,发现如果定义 a variable with __block,则 v̶i̶s̶i̶b̶i̶l̶i̶t̶y̶ _mutability_ of该变量扩展为block.

但由于某种原因,返回的 json 对象是 nil。我想知道为什么?

- (NSMutableDictionary *)executeRequestUrlString:(NSString *)urlString
{
__block NSMutableDictionary *json = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPShouldHandleCookies:YES];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];

NSString *cookieString = [self.userDefaults objectForKey:SAVED_COOKIE];

[request addValue:cookieString forHTTPHeaderField:@"Cookie"];

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue currentQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
                       {

                           NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);

                           NSError *error1;
                           NSMutableDictionary * innerJson = [NSJSONSerialization
                                   JSONObjectWithData:data
                                              options:kNilOptions
                                                error:&error1];
                           json = innerJson;

                       }];

    return json;
}
4

3 回答 3

20

首先,回答你的问题:

但由于某种原因,返回的 json 对象是nil. 我想知道为什么?

您返回的变量在您返回时尚未设置。您不能在sendAsynchronousRequest:queue:completionHandler:方法返回后立即收获结果:调用必须在回调您的块和设置json变量之前完成往返。

现在快速说明如何处理它:您的方法正在尝试将异步调用转换为同步调用。如果可以的话,尽量保持异步。与其期望一个返回 a 的方法,不如创建一个接受自己的块的方法,并在方法完成NSMutableDictionary*时将字典传递给该块:sendAsynchronousRequest:

- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(NSDictionary *jsonData))block {
    // Prepare for the call
    ...
    // Make the call
    [NSURLConnection sendAsynchronousRequest:request
                                    queue:[NSOperationQueue currentQueue]
                        completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
        NSError *error1;
        NSMutableDictionary * innerJson = [NSJSONSerialization
            JSONObjectWithData:data options:kNilOptions error:&error1
        ];
        block(innerJson); // Call back the block passed into your method
        }];

}
于 2012-09-10T13:46:41.827 回答
2

当您调用 时sendAsynchronousRequest:queue:completionHandler:,您已经请求了一个异步请求。因此它将请求和块排队并立即返回。在将来的某个时间发出请求,然后运行完成块。但到了那个时候,return json早就跑了。

如果您希望能够同步返回数据,那么您必须发出同步请求。这将挂起这个线程直到它完成,所以它不能是主线程。

于 2012-09-10T13:46:25.133 回答
0

使用以下代码转换来自服务器的数据时检查字符串:

 NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);

如果字符串是正确的 JSON 格式,那么只有你的 JSON 对象才是正确的。

希望这能帮到你!!

于 2016-04-16T07:53:25.587 回答