【问题标题】:Async request does not enter completion block异步请求未进入完成块
【发布时间】:2015-06-14 03:25:50
【问题描述】:

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

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

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

#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;
}

【问题讨论】:

    标签: ios objective-c arrays asynchronous


    【解决方案1】:

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

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

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

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

    在该代码中,UIApplicationMain 一直运行,直到它被中止或以其他方式终止。与此同时,类和实例如雨后春笋般涌现,它们持续存在,因为UIApplicationMain 不会停止。例如:

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

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

    【讨论】:

    • 是否存在main 持续足够长的时间以输入完成blocks 之一的情况,或者main 总是在blocks 之一开始之前终止。
    • 你需要一个运行循环。见stackoverflow.com/questions/2154600/…
    猜你喜欢
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多