Pan*_*ngu 6 grand-central-dispatch ios swift swift3
使用Swift 3,使用GCD已经改为DispatchGroup(),我正在尝试学习在我的代码中使用它.
目前我在另一个类中有一个函数,它试图下载文件并输出其速度.我希望首先完成该功能,因为我将其速度分配给var我将在第一个类中使用以执行依赖于此的其他任务var.
它是这样的:
二等:
func checkSpeed()
{
// call other functions and perform task to download file from link
// print out speed of download
nMbps = speedOfDownload
}
Run Code Online (Sandbox Code Playgroud)
头等舱:
let myGroup = DispatchGroup()
let check: SecondClass = SecondClass()
myGroup.enter()
check.checkSpeed()
myGroup.leave()
myGroup.notify(queue: DispatchQueue.main, execute: {
print("Finished all requests.")
print("speed = \(check.nMbps)")
})
Run Code Online (Sandbox Code Playgroud)
问题是Finish all requests首先获得输出,从而恢复nil了speed,那么以后checkSpeed完成并输出正确的下载速度.
我相信我做错了,但我不确定?
我如何确保在第一堂课speed完成后获得正确的价值checkSpeed?
细节与GitHub:connectedness.swiftcheckSpeed完全相同connectedToNetwork
您需要DispatchGroup.leave()在输入的任务完成后进行呼叫.因此,在您的代码中,myGroup.leave()需要放在checkSpeed()方法内的完成处理程序的末尾.
您可能需要像这样修改代码:
func checkSpeed(in myGroup: DispatchGroup) {
//...
...downLoadTask... {...its completion handler... in
//...
// print out speed of download
nMbps = speedOfDownload
myGroup.leave() //<- This needs to be placed at the end of the completion handler
}
//You should not place any code after invoking asynchronous task.
}
Run Code Online (Sandbox Code Playgroud)
并将其用作:
myGroup.enter()
check.checkSpeed(in: myGroup)
myGroup.notify(queue: DispatchQueue.main, execute: {
print("Finished all requests.")
print("speed = \(check.nMbps)")
})
Run Code Online (Sandbox Code Playgroud)
但是,正如vadian的评论或Pangu的回答所指出的,通常不会DispatchGroup用于单个异步任务.
加成
我需要说,我强烈建议在盘古的答案中显示完成处理程序模式.这是处理异步任务的更通用方法.
如果您修改checkSpeed()到checkSpeed(completion:)的建议,你可以很容易地实验DispatchGroup是这样的:
let myGroup = DispatchGroup()
let check: SecondClass = SecondClass()
let anotherTask: ThirdClass = ThirdClass()
myGroup.enter() //for `checkSpeed`
myGroup.enter() //for `doAnotherAsync`
check.checkSpeed {
myGroup.leave()
}
anotherTask.doAnotherAsync {
myGroup.leave()
}
myGroup.notify(queue: DispatchQueue.main) {
print("Finished all requests.")
print("speed = \(check.nMbps)")
}
Run Code Online (Sandbox Code Playgroud)
根据评论和此处找到的解决方案中提供的提示:来自 @vadian,由于我只执行一项任务,因此我使用了异步完成处理程序:
第二类:
func checkSpeed(completion: @escaping () -> ())
{
// call other functions and perform task to download file from link
// print out speed of download
nMbps = speedOfDownload
completion()
}
Run Code Online (Sandbox Code Playgroud)
头等舱:
let check: SecondClass = SecondClass()
check.checkSpeed {
print("speed = \(check.nMbps)")
}
Run Code Online (Sandbox Code Playgroud)
现在checkSpeed将首先完成并speed分配适当的值。
| 归档时间: |
|
| 查看次数: |
4784 次 |
| 最近记录: |