【问题标题】:iOS - How to know when NSOperationQueue finish processing a few operations?iOS - 如何知道 NSOperationQueue 何时完成处理一些操作?
【发布时间】:2012-04-17 10:02:01
【问题描述】:

我需要在我的应用程序中下载目录及其内容。所以我决定实现一个 NSOperationQueue 并将 NSOperation 子类化以实现 NSURLRequest 等...

问题是我一次添加了所有操作,但我无法确定何时下载了一个目录的所有文件以更新 UI 并启用此特定目录。

现在我必须等待所有目录中的所有文件都下载完毕才能更新 UI。

我已经为 NSOperationQueue 的 operationCount 和 NSOperation 的 isFinished 实现了键值观察,但我不知道一个目录什么时候有所有文件!

你有什么想法吗?

非常感谢

【问题讨论】:

标签: iphone ios ipad download nsoperation


【解决方案1】:

一种方法是创建某种 Directory 类,该类具有诸如 loadedCount(最初为 0)和 fileCount(初始化为目录中的许多文件)等属性,并在添加之前创建一个字典,将每个 NSOperation 映射到适当的目录对队列的操作。在 isFinished 回调中,您可以将给定 NSOperation 的 Directory 对象从字典中拉出,并将 directory.loadedCount 增加 1。如果您的 directory.loadedCount == directory.fileCount,则触发对 UI 的更新。

【讨论】:

  • 这是我的第一个想法。但我想知道这是否是正确的方法,或者是否有更好的方法。
【解决方案2】:

您可以重构代码以避免一次将所有请求排入队列。 Enqueue 一次只请求一个目录。当operationCount 达到零时,您可以确定所有请求都已完成或失败,更新 UI 并将请求排入下一个目录。继续直到目录数组为空。

优点是:

  • 相对简单
  • 您不必只查询文件系统来确定已下载的内容
  • 如果需要,您可以在不更改其他逻辑的情况下重新排队失败的请求。

【讨论】:

    【解决方案3】:

    添加一个“完成”NSOperation,它具有一个目录的所有其他NSOperations 作为依赖项。

    类似这样的:

    NSInvocationOperation *doneOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(done:) object:nil];
    
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
    [queue addOperation:op1];
    [doneOp addDependency:op1];
    
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
    [queue addOperation:op2];
    [doneOp addDependency:op2];
    
    NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
    [queue addOperation:op3];
    [doneOp addDependency:op3];
    
    [queue addOperation:doneOp];
    

    doneOp 只会在 op1op2op3 执行完毕后运行。

    【讨论】:

    • 我忘了说我的操作是并发的。你的例子还可以吗?
    • 当然,这就是依赖的全部意义所在。在非并发操作队列中,您只需按正确顺序添加操作即可实现相同目的。但是一个操作在其所有依赖项都执行完毕后才会运行。
    • 向你致敬。这正是我想要的!
    • 它比 KVO 方法更好,因为它更安全、更直接。
    • 在将操作添加到队列之前/之后添加依赖关系是否重要?
    【解决方案4】:
    [opQueue operationCount]

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多