从 ViewController 函数循环中更新 NSProgress 显示

Update NSProgress display from within ViewController Function Loop

我又回来了蜂群思维!

在我的 ViewController class 中,我有一个函数可以遍历数组中的一系列项目。我想要发生的是在循环的每次迭代中更新我的进度条,但它似乎在完成整个循环并退出我的函数之前不会更新屏幕上的进度条。

我很确定这只是因为每次通过应用程序循环只重绘一次视图(我在这里可能没有使用正确的术语。)

在我仍在 ViewController 函数循环中时强制更新 ViewController 视图的正确方法是什么?

这基本上是我现在正在做的事情:

func myFunction() {
     for item in collection {
         progressBar.increment(by:1)
         progressBar.display()
     }
     // execute my other code
}

当这不起作用时,我尝试在 progressBar.draw 方法之后添加一个 needsSetDisplay,如下所示:

func myFunction() {
     for item in collection {
         progressBar.increment(by:1)
         progressBar.display()
         let rect = self.view.visibleRect
         self.view.needsSetDisplay(rect)
     }
     // execute my other code
}

但是还是不行。

我确定有一种方法可以完成我需要做的事情,但我怀疑它涉及一些更高级的东西,例如 运行 多进程,我可能没有资格做然而,由于我是 Swift 的新手,而且我用 Obj-C 编写代码已经至少 10 年了(也就是我忘记了我所知道的大部分内容。)

谢谢!

EDIT 另一件我尝试失败的事情是调用 progressBar.displayAsNeeded() 但它似乎也没有用。

假设您 运行 在主线程上,那么您将阻塞直到方法完成。无论您尝试使用哪种 'need' 样式方法(setNeedsDisplay、displayAsNeeded 等),实际的重新显示都不会发生,直到该方法完成(显示更新被分组以避免它被不断更新)。

你可以做的是将工作放在后台线程上,然后将 UI 更新放回主线程,类似于这样:

DispatchQueue.global(qos: .background).async {
    for item in collection {
        DispatchQueue.main.async {
            progressBar.increment(by:1)
            progressBar.display()
        }
    }
}

当然这会引发其他问题,例如用户现在可以在后台线程正在处理时与 UI 交互,您需要考虑这一点。

如果您已经 运行 在后台线程中,那么您只需将进度条更新分派到主线程。