从NSURLResponse完成块中获取数据

bra*_*ray 8 objective-c nsurlconnection ios objective-c-blocks

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

在我的代码中,我必须asychronous block从' outer'方法中返回要返回的JSON数据.我variable with __block用谷歌搜索,发现如果定义一个,_mutability_ of那么变量就被扩展到了变量v̶i̶s̶i̶b̶i̶l̶i̶t̶y̶ 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;
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 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
        }];

}
Run Code Online (Sandbox Code Playgroud)