NSOperationQueue INSIDE a NSOperation

Its*_*ret 2 cocoa-touch objective-c nsoperation nsoperationqueue afnetworking

我创建了一个NSOperation目标是从20个URL下载一些图像(如20).所以在这里NSOperation我创建20 AFImageRequestOperation添加它们NSOperationQueue并调用-waitUntilAllOperationsAreFinished队列.

问题是,它不等待,它立即返回.这是代码

- (void)main {
    NSArray *array = [I have the 20 links stored in this array];

    self.queue = [[NSOperationQueue alloc]init];
    self.queue.maxConcurrentOperationCount = 1;

    for (int i = 0; i < array.count; i++) {                
        NSURL *url = [NSURL URLWithString:[array objectAtIndex:i]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        AFImageRequestOperation *op = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:^UIImage *(UIImage *image) {
            return image;
        } success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
        // SUCCESS BLOCK (not relevant)
        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        // FAILURE BLOCK (not relevant)
        }];

        [self.queue addOperation:op];
    }

    [self.queue waitUntilAllOperationsAreFinished]; // Here is the problem it doesn't wait
    DDLogWarn(@"-- %@ FINISHED --", self);

}
Run Code Online (Sandbox Code Playgroud)

在控制台中,DDLogWarn(@"-- %@ FINISHED --", self);每次操作之前的打印都开始了,所以我的猜测是waitUntilAllOperationsAreFinished没有完成它的工作并且没有等待,但是20个操作仍在运行之后,这可能意味着main还没有返回,所以我不知道该怎么想.

编辑1:其实我想知道,如果我的DDLog内部成功和失败阻止因为waitUntilAllOperationsAreFinished阻塞线程直到所有操作完成.这可以解释为什么我没有看到任何事情发生,突然间.

Ror*_*yan 5

我发现创建一个NSOperation包含其他的东西是有用的,NSOperations出于类似的原因,即我有很多较小的任务构成一个更大的任务,我想把更大的任务当作一个单元处理,并在它有时通知完成.我还需要序列化较大任务的运行,因此一次只运行一个,但是当每个大任务运行时,它可以在自身内执行多个并发操作.

在我看来,像你一样,创建一个NSOperation管理大任务是一个很好的方法,而且我没有在文档中读到任何不这样做的东西.

看起来您的代码可能正常工作,因此您可以继续使用NSOperation.

根据您的情况阻塞线程可能是合理的.如果阻塞不合理但你想继续使用NSOperation,你需要创建一个"并发" NSOperation参见并发编程指南:配置并发执行操作

如果您一次只允许一个图像下载,您可以使用@jackslashs建议来表示操作结束,或者如果您想允许并发图像下载,那么您可以使用单个NSBlockOperation作为最终操作并使用-[NSOperation addDependency:]它来使其依赖在所有其他操作上,所以它将运行最后.

当您收到所有内容已完成的信号时,您可以按照文档中的说明适当地设置isFinished和isExecuting标记以完成主要操作NSOperation.

不可否认,这有一定程度的复杂性,但您可能会发现它很有用,因为一旦将复杂性隐藏在NSOperation外部代码中,可能就像我的情况一样简单.

如果你决定创建一个Concurrent,NSOperation你可能会发现Apple示例代码LinkedImageFetcher:QRunLoopOperation作为起点很有用.