objective-c - 从 NSURLResponse 完成 block 中获取数据

标签 objective-c ios nsurlconnection objective-c-blocks

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

在我的代码中,我必须从 asychronous block 中取出 JSON 数据,以便从“outer”方法返回。我用 google 搜索发现,如果用 __block 定义一个变量,该变量的 v̶i̶s̶i̶b̶i̶l̶i̶t̶y̶ _mutability_ 被扩展到 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;
}

最佳答案

首先,回答你的问题:

But for some reason returned json object is nil. I wonder why?

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

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

- (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
        }];

}

关于objective-c - 从 NSURLResponse 完成 block 中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12352901/

相关文章:

ios - 从数组中检索字符串时遇到问题

iphone - Git本地仓库管理

iphone - 调用 NSURLConnectionDataDelegate 方法来下载图像只是偶尔有效

iphone - NSURLConnection 不返回数据

ios - 将 UIVisualEffectView 添加到 UITableView 的背景 View 仅适用于模拟器而非设备

ios - 在具有转换单元格的 collectionView 上使用 indexPathForItemAtPoint

ios - 无法启动iphone模拟器; "not responding"。 Xcode 7,模拟器版本 9(适用于 iOS 9)

objective-c - 无法从 connectionDidFinishLoading 中的数据解析 JSON – 也许是数据太多了?

iphone - 如何从 uinavigationcontroller 堆栈中删除特定的 View Controller ?

ios - 将 Ruby bundler gems 作为 Xcode 构建脚本运行