【问题标题】:Why is a process suspended by another process behind it?为什么一个进程被它后面的另一个进程挂起?
【发布时间】:2021-02-11 02:59:51
【问题描述】:

代码很简单,只读取一个xml文件并将其解析成一个数组。直到有一天我试图打开一个 big xml 文件时,我才注意到这个问题。

我在解析数据时使用 NSProgressIndicator 添加了一个模糊视图,但是直到解析完成后,模糊视图才显示出来。

self.addBlurView()
let file = HandleFile.shared.openFile(filePath)
self.removeBlurView()
guard let name = file.name, let path = file.path, let data = file.data else {
    return
}

所以我尝试延迟解析数据。模糊视图可以显示,完成后可以移除。

self.addBlurView()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
    let file = HandleFile.shared.openFile(filePath)
    self.removeBlurView()
    guard let name = file.name, let path = file.path, let data = file.data else {
        return
    }
})

我认为这可能是线程的问题,所以我在func addBlurView() 中尝试了这个,失败。我也尝试在addBlurView()中添加计数,计数到一定数量后暂停,解析数据后继续计数。

DispatchQueue.main.async {
    self.blurView.isHidden = false
    self.spinner.startAnimation(self)
}

不知道为什么会这样。谁能帮忙解决这个问题?

谢谢。

【问题讨论】:

  • 尝试将let file = HandleFile.shared.openFile(filePath) 包裹在DispatchQueue.global(qos: .default).async 主队列是一个串行队列,分配给它的所有任务都由主线程串行执行。一般来说,您不应该在主线程上执行任何繁重的任务(例如将文件加载到内存),因为它会阻塞主线程并导致 UI 无响应。如果没有实际看到openFile( 的实现,很难回答,但通常此类任务应该有完成块来告诉您文件已加载,并且在该块中您可以切换到主队列并删除 blurV
  • 是的,把所有的东西都放在DispatchQueue.global(qos: .default).async,然后更新主队列中的UI,它工作正常。谢谢。您介意将其发布为答案以便我接受吗?
  • 似乎您对答案投了赞成票但尚未接受,要接受答案,请点击上下箭头下方的勾号:)
  • 抱歉耽搁了,再次感谢。

标签: swift multithreading macos cocoa process


【解决方案1】:

正如我在上面的 cmets 中提到的,主队列是一个串行队列,分配给它的所有任务都由主线程串行执行。一般来说,您不应该在主线程上执行任何繁重的任务(例如将文件加载到内存),因为它会阻塞主线程并导致 UI 无响应。

通常,所有繁重的任务,例如将文件加载到内存(任何不直接处理 UI 渲染的事情)都应该委托给调度队列之一。尝试将您的 openFile(filePath) 调用封装在 DispatchQueue

        self.addBlurView()
        DispatchQueue.global(qos: .default).async {
            let file = HandleFile.shared.openFile(filePath)
        }

我个人希望openFile 函数有一个完成块,当它完成加载文件时会在主队列上触发,这样您就可以删除您的 blurView,但在您的情况下,它似乎是一个同步语句,所以您可以尝试

        self.addBlurView()
        DispatchQueue.global(qos: .default).async {
            let file = HandleFile.shared.openFile(filePath)
            DispatchQueue.main.async {
                self.removeBlurView()
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-12
    • 2023-01-30
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多