我们的iPhone应用程序代码目前使用NSURLConnection sendSynchronousRequest并且工作正常,但我们需要更多地了解连接进度和缓存,因此我们将转向异步NSURLConnection。
等待异步代码完成的最简单方法是什么?把它包裹在NSOperation / NSOperationQueue中,执行选择......,还是什么?
感谢。
答案 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
对象。