iOS中具有进度报告的可取消异步操作集 [英] Cancellable set of asynchronous operations with progress reporting in iOS
问题描述
假设我使用另一个SDK(我无法控制)和一个异步导入1个文件的API,并在完成时调用完成回调。
以下是一个示例API。
Suppose that I use another SDK (which I do not have control of) with an API that imports 1 file asynchronously, and calls a completion callback on completion. The following is an example API.
func importFile(filePath: String, completion: () -> Void)
我需要使用此API导入10个文件(逐个),但我需要它可以取消,例如在成功导入文件1,2,3之后,在导入文件4时,我希望能够取消整个操作集(导入10个文件),这样文件4就会完成(因为它已经开始了) ),但不再导入文件5-10。
I need to import 10 files (one by one) using this API, but I need it to be cancellable, e.g. after Files 1,2,3 has been successfully imported, while File 4 is being imported, I want to be able to cancel the whole set of operations (import of the 10 Files), such that File 4 will finish (since it already started), but Files 5-10 will not be imported anymore.
此外,我还需要报告导入的进度。成功导入文件1后,我应该报告10%的进度(10个中有1个已完成)。
In addition, I also need to report progress of the import. When File 1 has been imported successfully, then I should report progress of 10% (1 out of 10 has been finished).
我如何实现这一目标?
我正在考虑使用NSOperationQueue和10个NSOperations,但似乎进度报告很难。
I am considering using NSOperationQueue with 10 NSOperations, but it seems that progress reporting will be difficult.
推荐答案
所以,我相信你想从你的问题中得到以下内容:
So, I believe that this is the following you want from your question:
- 逐个导入n个文件队列
- 导入每个文件时的报告进度
- 能够在中间取消操作
可以通过以下方式使用 NSOperationQueue
和 NSBlockOperation
来实现。
It can be achieved using NSOperationQueue
and NSBlockOperation
in the following way.
- 创建
AsyncBlockOperation
和NSOperationQueue + AsyncBlockOperation
来自以下StackOverflow问题的答案中给出的代码类: NSOperation等待异步块执行 - 将这两个类导入到将要使用的文件中
-
创建操作队列
- Create
AsyncBlockOperation
andNSOperationQueue+AsyncBlockOperation
classes from code given in answer for the following StackOverflow question: NSOperation wait until asynchronous block executes - Import both the classes into the file they are going to be used
Create an operation queue
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 1;
operationQueue.name = @"com.yourOrganization.yourProject.yourQueue";
创建一个函数,为您提供回调以获取进展
Create a function which gives you a callback for getting progress
- (void)importFilesFromFilePathArray:(NSArray *)pathsArray
inOperationQueue:(NSOperationQueue *)operationQueue
withProgress:(void (^)(CGFloat progress))progressBlock {
}
在 2
中定义的函数,使用 NSBlockOperation
在 NSOperationQueue $ c中执行操作$ c>
Inside the function defined in 2
, use NSBlockOperation
for performing your operations in the 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();
}];
}];
}
对于取消操作,我们只需使用我们在第一步创建的operationQueue
[operationQueue cancelAllOperations];
我自己试过这段代码。它运作良好。随意提出改进建议,使其更好:)
I tried this code myself. It's working well. Feel free to suggest improvements to make it better :)
这篇关于iOS中具有进度报告的可取消异步操作集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!