iOS中具有进度报告的可取消异步操作集

假设我使用另一个SDK(我无法控制)和一个异步导入1个文件的API,并在完成时调用完成回调.

以下是一个示例API.

func importFile(filePath: String, completion: () -> Void)

我需要使用此API导入10个文件(逐个),但我需要它可以取消,例如在成功导入文件1,2,3之后,在导入文件4时,我希望能够取消整个操作集(导入10个文件),这样文件4就会完成(因为它已经开始了) ),但不再导入文件5-10.

另外,我还需要报告导入的进度.当文件1成功导入后,我应该报告10%的进度(10个中的1个已经完成).

我怎样才能做到这一点?

我正在考虑使用NSOperationQueue和10个NSOperations,但似乎进度报告很难.

最佳答案 所以,我相信你想从你的问题中得到以下内容:

>在队列中逐个导入n个文件
>报告导入每个文件的进度
>能够在中间取消操作

可以通过以下方式使用NSOperationQueue和NSBlockOperation来实现.

>从以下StackOverflow问题的答案中给出的代码中创建AsyncBlockOperation和NSOperationQueue AsyncBlockOperation类:NSOperation wait until asynchronous block executes
>将这两个类导入到将要使用的文件中
>创建一个操作队列

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 1;
operationQueue.name = @"com.yourOrganization.yourProject.yourQueue";

>创建一个函数,为您提供回调以获得进度

- (void)importFilesFromFilePathArray:(NSArray *)pathsArray
                    inOperationQueue:(NSOperationQueue *)operationQueue
                        withProgress:(void (^)(CGFloat progress))progressBlock {

  }

>在2中定义的函数内,使用NSBlockOperation在NSOperationQueue中执行操作

for (int i = 0; i < pathsArray.count; i++) {

    [operationQueue addAsyncOperationWithBlock:^(dispatch_block_t completionHandler) {
        [self importFile:(NSString *)[pathsArray objectAtIndex:i] completion:^(bool completion) {
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                CGFloat progress = (100 * (float)(i+1)/pathsArray.count);
                progressBlock(progress);
                if (progress == 100) {
                   successBlock(YES);
                }
             }];
             completionHandler();
         }];
     }];
}

>对于取消操作,我们可以简单地使用我们在第1步中创建的operationQueue

[operationQueue cancelAllOperations];

我自己试过这段代码.它运作良好.随意建议改进,使其更好:)

点赞