为什么一个进程被它后面的另一个进程挂起?

Why is a process suspended by another process behind it?

代码比较简单,就是读取一个xml文件,解析成一个数组。直到有一天我试图打开一个 xml 文件时,我才注意到这个问题。

我在解析数据的时候用NSProgressIndicator添加了一个blur view,但是直到解析完成后blur view才出现。

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)
}

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

谢谢。

正如我在上面的评论中提到的,主队列是一个串行队列,分配给它的所有任务都由主线程串行执行。通常,您不应在主线程上执行任何繁重的任务(如将文件加载到内存中),因为它会阻塞主线程并导致 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()
            }
        }