Swift-强制同步执行工作和后续的UI渲染

时间:2018-09-01 08:47:52

标签: swift multithreading synchronous

我有一段遵循工作流程的代码:

for index in 0..<self!.recordedData.count {
//Do work here that involves fetching data from coredata and prerendering an image for each index
}
reloadUIWithData()

工作流程应为:

  1. for循环中的所有工作都将完成

  2. 要执行的ReloadUIWithData。

但是,在循环工作完成之前,将调用reloadUIWithData函数。有什么方法可以强制所有工作在for循环中完全完成,然后再执行reloadUIWithData?

我尝试了以下DispatchQueue扩展:

static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {

    DispatchQueue.global(qos: .background).sync {
        background?()
        if let completion = completion {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
                completion()
            })
        }
    }
}

通过以下方式:

DispatchQueue.background(delay: 0.01, background: {
for index in 0..<self!.recordedData.count {
    //Do work here that involves fetching data from coredata and rendering an image for each index
    }
}, completion:{
reloadUIWithData()
}

但是,这似乎无法以可扩展的方式工作。如果将delay参数设置为类似0.5的效果,但是将delay参数设置为较小的值(如0.01)会导致相同的问题。我想使用一种比设置随机延迟更可靠的方法,并希望所有工作在该时间段内完成。

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

有专用的API DispatchGroup可以做到这一点。但是,它不会使异步任务同步。就像一个计数器,它在enter上递增,在leave上递减,并在循环中的所有任务完成时( counter == 0)通知notify

let group = DispatchGroup()
for index in 0..<self!.recordedData.count {
    group.enter()
    doAsynchronousStuff { result in
        // do something with result
        group.leave()
    }
}
group.notify(queue: DispatchQueue.main) {
    self.reloadUIWithData()
}