使用Swift 3中的DispatchGroup()执行任务?

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首先获得输出,从而恢复nilspeed,那么以后checkSpeed完成并输出正确的下载速度.

我相信我做错了,但我不确定?

我如何确保在第一堂课speed完成后获得正确的价值checkSpeed

细节与GitHub:connectedness.swiftcheckSpeed完全相同connectedToNetwork

OOP*_*Per 8

您需要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)

  • _`DispatchGroup`主要用于异步任务组?_对.`DispatchGroup`旨在与多个异步任务一起使用,以期在**所有**组中的任务完成时得到通知.当在组中输入的所有任务都调用了`DispatchGroup.leave()`时,将调用使用`notify(queue:execute:)`指定的闭包. (3认同)

Pan*_*ngu 3

根据评论和此处找到的解决方案中提供的提示:来自 @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分配适当的值。