iOS – NSOperation内的asynchronousNSURLConnection

我知道这个问题在这个问题上被问了很多次,但是我没有设法使它在我的项目中工作。

所以,我想要NSOperation子类,并使用NSURLConnection下载文件。 什么是正确的方法来做到这一点? 这是我的代码不起作用:首先,我将所有的操作添加到循环中:

 DownloadFileOperation *operation; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; for (int i=0; i<10; i++) { operation = [[DownloadFileOperation alloc] init]; operation.urlString = pdfUrlString; [queue addOperation:operation]; operation = nil; } 

这是我的子类:

 @interface DownloadHandbookOperation : NSOperation <NSURLConnectionDelegate> { } @property (strong, nonatomic) NSString *urlString; @end @implementation DownloadHandbookOperation { NSString *filePath; NSFileHandle *file; NSURLConnection * connection; } - (void)start { if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; return; } NSURL *url = [[NSURL alloc] initWithString:[self.urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; [req addValue:@"Basic ***=" forHTTPHeaderField:@"Authorization"]; connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES]; } - (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response { NSString *filename = [[conn.originalRequest.URL absoluteString] lastPathComponent]; filename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filename]; [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; file = [NSFileHandle fileHandleForUpdatingAtPath:filePath] ; if (file) { [file seekToEndOfFile]; } else [self finish]; } - (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data { if (file) { [file seekToEndOfFile]; } [file writeData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)conn { [file closeFile]; [self finish]; } - (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error { connection = nil; [self finish]; } - (void)cancel { [super cancel]; [connection cancel]; } - (void)finish { NSLog(@"operationfinished."); } @end 

我究竟做错了什么?

您需要正确configuration您的操作以执行“并发操作”

并发编程指南:为并发执行configuration操作

您需要返回isConcurrent = YES并正确pipe理其他状态标志, isExecutingisFinished在KVO兼容的方式。


为了说明这里的总体思路,Pulse的工程师发表了一篇文章,介绍了他们的解决scheme,并提供了一些易于使用的演示代码,您可以下载和查看。

脉冲工程博客:使用NSOperationQueues的并发下载 **

这段代码还通过确保在主线程上启动NSURLConnection,从而在具有主动runloop的线程上启动NSURLConnection。

(**链接现在到archive.org,我认为脉搏被收购,并把他们的旧网站下来)