NSURLConnection - 如何等待完成

时间:2009-05-05 14:41:39

标签: iphone cocoa-touch

我们的iPhone应用程序代码目前使用NSURLConnection sendSynchronousRequest并且工作正常,但我们需要更多地了解连接进度和缓存,因此我们将转向异步NSURLConnection。

等待异步代码完成的最简单方法是什么?把它包裹在NSOperation / NSOperationQueue中,执行选择......,还是什么?

感谢。

4 个答案:

答案 0 :(得分:4)

我正在回答这个问题,万一其他人将来会遇到这个问题。 Apple的URLCache示例代码就是如何完成此操作的一个很好的例子。您可以在以下网址找到它:

正如约翰在上面的评论中指出的那样 - 不要阻止/等待 - 通知。

答案 1 :(得分:2)

要异步使用NSURLConnection,在initWithRequest中初始化时提供委托:delegate:。委托应该实现NSURLConnection委托方法。 NSURLConnection处理在另一个线程上进行,但在启动相关NSURLConnection对象的异步加载操作的线程上调用委托方法。

答案 2 :(得分:2)

除了前面提到的通知之外,一种常见的方法是让需要了解URL加载完成的类本身设置为处理URL回调的类的委托。然后,当URL加载完成时,调用委托并告知加载已完成。

实际上,如果你阻止线程连接将永远不会去任何地方,因为它在同一个线程上工作(是的,即使你使用的是异步方法)。

答案 3 :(得分:2)

我遇到了这个问题,因为我们的应用程序在很多有意义的地方使用了NSURLConnection sendSynchronousRequest,比如在后台线程上进行一些处理,偶尔需要额外的数据来完成处理。像这样:

// do some processing
NSData * data = someCachedData;
if (data = nil) {
    data = [NSURLConnection sendSynchronousRequest....]
    someCachedData = data;
}
// Use data for further processing

如果您在同一个流程中有3个不同的地方,那么将其分解为单独的函数可能并不理想(或者如果您有足够大的代码库,则根本不可行)。

在某些时候,我们需要为我们的连接设置代表(进行SSL证书固定),然后我在互联网上寻找解决方案,而且所有内容都是以下形式:“只使用异步并且不要对抗框架! ”。好吧,sendSynchronousRequest存在是有原因的,这是如何使用底层异步连接重现它:

 + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__autoreleasing *)response error:(NSError *__autoreleasing *)error
 {
     static NSOperationQueue * requestsQueue;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
         requestsQueue = [[NSOperationQueue alloc] init];
         requestsQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
     });

     NSCondition * waitLock = [NSCondition new];
     [waitLock lock];

     __block NSError * returnedError;
     __block NSURLResponse * returnedResponse;
     __block NSData * returnedData;
     __block BOOL done = NO;
     [NSURLConnection sendAsynchronousRequest:request
                                        queue:requestsQueue
                            completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError){

                     returnedError = connectionError;
                     returnedResponse = response;
                     returnedData = data;
                     [waitLock lock];
                     done = YES;
                     [waitLock signal];
                     [waitLock unlock];
                 }];
     if (!done) {
         [waitLock wait];
     }
     [waitLock unlock];
     *response = returnedResponse;
     *error = returnedError;
     return returnedData;
 }

发布在这里以防万一有人像我一样来看。

请注意,NSURLConnection sendAsynchrounousRequest可以替换为您用于发送异步请求的任何方式,例如使用委托或其他内容创建NSURLConnection对象。