异步请求不进入完成块 [英] Async request does not enter completion block

查看:34
本文介绍了异步请求不进入完成块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码是为了让我更好地理解[NSURLConnection sendAsynchronousRequest:queue:completionHandler].

The following code is an attempt to me better understand [NSURLConnection sendAsynchronousRequest:queue:completionHandler].

completionHandler 块中有 NSLog 语句,但是当我在命令行项目的 XCode 中的 main.m 中运行它时,它永远不会进入 completionHandler 块.我试过使用不同的队列,mainQueuecurrentQueue,但都不起作用.

There are NSLog statements in the completionHandler block, but when I run this in main.m in XCode from a command line project, it never enters the completionHandler blocks. I've tried using the different queues, mainQueue and currentQueue but neither work.

我的预感是队列在请求完成之前被释放并且涉及到保留周期.

My hunch is that the queue is being deallocated before the request is completed and that retain cycles are involved.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSCache *myCache = [[NSCache alloc] init];

        NSArray *images = @[
         @"http://i.stack.imgur.com/E66qr.png",
         @"http://www.tiempoyquimera.com/wp-content/uploads/2010/01/Euro-Trash-Girl-2010.jpg",
         @"http://1.bp.blogspot.com/-Mxd8AB2nbQY/UYCISJiQz3I/AAAAAAAAAH8/Tc43U8aa9dM/s1600/Tarantino10colhans_1460858i.jpg",
         @"https://awestruckwanderer.files.wordpress.com/2014/02/alan-watts.png",
         @"http://www.esalen.org/sites/default/files/photo_images/20120201_DELLIS__MG_9612_711.jpg"];

        for (NSString *image in images){
            NSURL *myURL = [NSURL URLWithString:image];
            NSURLRequest *request = [[NSURLRequest alloc] initWithURL:myURL];

            NSLog(@"Can handle request %@", @([NSURLConnection canHandleRequest:request]));
            NSOperationQueue *queue = [[NSOperationQueue alloc]init];

            [NSURLConnection sendAsynchronousRequest:request
                                               queue:[NSOperationQueue mainQueue]
                                   completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                                       NSLog(@"In the completion handler");
                                       if (!error)
                                       {
                                           // save data to cache with url as key
                                           NSLog(@"Image Added to Cache");
                                           [myCache setObject:data
                                                       forKey:myURL];
                                       } else
                                       {
                                           NSLog(@"Image Not Added to Cache");
                                       }
                                   }];
        }
    }
    return 0;
}

推荐答案

我的预感是队列在请求完成之前被释放并且涉及到保留周期

My hunch is that the queue is being deallocated before the request is completed and that retain cycles are involved

不完全是.不涉及保留周期.涉及持久性.您在 main 函数中执行此操作.它立即退出——异步的东西(网络和随后的回调)是异步的,所以它会稍后出现,如果我们有任何持久性.但我们没有.main 退出,这意味着整个该死的程序被拆除,kaboom,在有任何机会进行任何网络之前,更不用说联网后回调完成处理程序.

Not quite. Retain cycles are not involved. Persistence is involved. You are doing this in a main function. It exits immediately - the asynchronous stuff (the networking and the subsequent callback) is asynchronous, so it would come later, if we had any persistence. But we don't. main exits, and that means that the whole darned program is torn down, kaboom, before there is any opportunity to do any networking, let alone call back into the completion handler after the networking.

现在将此与现实生活中发生的事情进行对比.在真正的 iOS 应用中,main不会退出,因为它调用了 UIApplicationMain,循环直到应用终止.

Now contrast this with how things happen in real life. In a real iOS app, main does not exit, because it calls UIApplicationMain, which loops until the app is terminated.

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil,
            NSStringFromClass([AppDelegate class]));
    }
}

在该代码中,UIApplicationMain 会一直运行,直到它被中止或以其他方式终止.同时,类和实例也开始活跃起来,并且它们一直存在,因为 UIApplicationMain 不会停止.例如:

In that code, UIApplicationMain just keeps running until it is aborted or otherwise terminated. Meanwhile, classes and instance have sprung to life, and they persist, because UIApplicationMain does not stop. For example:

@implementation MyViewController
- (void) someMethod {
    // ...
    [NSURLConnection sendAsynchronousRequest:request
         queue:[NSOperationQueue mainQueue]
         completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
             // ...
    }
}
@end

现在,在某种意义上,完全相同的事情发生了:someMethod 立即退出.但是我们的程序总体上还在运行!UIApplicationMain 有一个运行循环并且该运行循环仍在循环中.因此,事情继续存在,所以现在异步材料可以发生 - 我们可以联网然后调用回调.

Now, in one sense, exactly the same thing happens: someMethod exits immediately. But our program overall is still running! UIApplicationMain has a run loop and that run loop is still cycling. Thus, things live on, and so now the asynchronous material can happen - we can network and then call the callback.

这篇关于异步请求不进入完成块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆