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

Ios 在Swift 3中使用DispatchGroup()执行任务?,ios,swift,swift3,grand-central-dispatch,Ios,Swift,Swift3,Grand Central Dispatch,在Swift 3中,使用GCD已更改为DispatchGroup(),我正在尝试在代码中使用它 目前,我在另一个类中有一个函数,它尝试下载一个文件并输出其速度。我喜欢先完成该函数,因为我将其速度分配给一个var,我将在第一个类中使用它来执行依赖于该var的其他任务 事情是这样的: func checkSpeed(in myGroup: DispatchGroup) { //... ...downLoadTask... {...its completion handler... i

在Swift 3中,使用GCD已更改为
DispatchGroup()
,我正在尝试在代码中使用它

目前,我在另一个类中有一个函数,它尝试下载一个文件并输出其速度。我喜欢先完成该函数,因为我将其速度分配给一个
var
,我将在第一个类中使用它来执行依赖于该
var
的其他任务

事情是这样的:

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.
}
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)")
}
二等舱:

func checkSpeed()
{
    // call other functions and perform task to download file from link

    // print out speed of download

    nMbps = speedOfDownload
}
头等舱:

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)")
})
let check: SecondClass = SecondClass()

check.checkSpeed {
print("speed = \(check.nMbps)")

}
问题是
Finish all requests
首先获得输出,因此
speed
返回
nil
,然后
checkSpeed
完成并输出正确的下载速度

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

在我的第一节课中完成
checkSpeed
后,如何确保
speed
获得正确的值


checkSpeed
的详细信息与GitHub中的
ConnectedNetwork
完全相同:

,此处的注释和解决方案中提供了提示:,因为我只执行一项任务,所以我使用了异步完成处理程序:

二等舱:

func checkSpeed(completion: @escaping () -> ())
{
    // call other functions and perform task to download file from link

    // print out speed of download

    nMbps = speedOfDownload
    completion()

}
头等舱:

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)")
})
let check: SecondClass = SecondClass()

check.checkSpeed {
print("speed = \(check.nMbps)")

}

现在,
checkSpeed
将首先完成,并且为
speed
分配了适当的值。

您需要在输入的任务完成后调用
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.
}
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)")
}
但是,正如瓦迪安的评论或Pangu的回答中所指出的,对于单个异步任务,通常不使用
DispatchGroup


添加

我需要说的是,我强烈推荐盘古回答中所示的完成处理程序模式。这是处理异步任务的更通用的方法

如果您已按照建议将
checkSpeed()
修改为
checkSpeed(completion:)
,您可以像这样轻松地试验
DispatchGroup

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

这取决于
checkSpeed()
调用下载任务的方式。你需要展示该方法的更多细节。如果你谈论的是一个文件,你需要一个异步完成处理程序,而不是一个组。OOPer:抱歉,GCD从一开始就把我弄糊涂了,但没有太多细节,
DispatchGroup
group主要用于……组异步任务?
DispatchGroup
主要用于组异步任务?对<代码>调度组
用于多个异步任务,以便在组中的所有任务完成时收到通知。当组中输入的所有任务都调用了
DispatchGroup.leave()
时,将调用用
notify(队列:execute:)
指定的闭包。