Swift - Force Synchronous Execution of Work and Subsequent UI Rendering

拜拜、爱过 提交于 2019-12-18 09:52:49

问题


I have a piece of code that follows the workflow:

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

The workflow is intended to be:

  1. All work in the for loop to be completed

  2. ReloadUIWithData to be executed.

However, the reloadUIWithData function is being called before the work in the loop is finished. Is there any way to enforce that all work is completely finished inside the for loop, and then executing reloadUIWithData afterwards?

I have tried the following DispatchQueue Extension:

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

By means of:

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

But this doesn't seem to work in a scalable manner. While it works if the delay parameter is set to something like 0.5, setting the delay parameter to a small value such as 0.01 causes the same issue to happen. I'd like to use a more robust method than setting a random delay and hope that all work gets done within that time span.

Any help would be greatly appreciated. Thanks!


回答1:


There is a dedicated API DispatchGroup to do that. However it doesn't make the asynchronous tasks synchronous. It's like a counter which increments on enter, decrements on leave and notifies on notify when all tasks in the loop are completed (counter == 0).

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


来源:https://stackoverflow.com/questions/52126494/swift-force-synchronous-execution-of-work-and-subsequent-ui-rendering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!