草庐IT

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

coder 2023-09-29 原文

假设我使用另一个 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 一起使用,但似乎很难报告进度。

最佳答案

因此,我相信这是您希望从问题中得到的以下信息:

  1. 在队列中逐一导入n个文件
  2. 导入每个文件时报告进度
  3. 能够在中间取消操作

可以通过以下方式使用NSOperationQueueNSBlockOperation来实现。

  1. 根据以下 StackOverflow 问题的答案中给出的代码创建 AsyncBlockOperationNSOperationQueue+AsyncBlockOperation 类:NSOperation wait until asynchronous block executes
  2. 将这两个类导入到它们将要使用的文件中
  3. 创建一个操作队列

    NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
    operationQueue.maxConcurrentOperationCount = 1;
    operationQueue.name = @"com.yourOrganization.yourProject.yourQueue";
    
  4. 创建一个函数,为您提供获取进度的回调

    - (void)importFilesFromFilePathArray:(NSArray *)pathsArray
                        inOperationQueue:(NSOperationQueue *)operationQueue
                            withProgress:(void (^)(CGFloat progress))progressBlock {
    
      }
    
  5. 2 中定义的函数内,使用 NSBlockOperationNSOperationQueue

    中执行您的操作
    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();
             }];
         }];
    }
    
  6. 对于取消操作,我们可以简单地使用我们在第一步中创建的operationQueue

    [operationQueue cancelAllOperations];
    

我自己试过这段代码。它运作良好。随时提出改进建议,使其变得更好:)

关于ios - iOS 中带有进度报告的可取消异步操作集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40265055/

有关ios - iOS 中带有进度报告的可取消异步操作集的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  5. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  8. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  9. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  10. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

随机推荐