调度组永远等待

Fer*_*rox 7 grand-central-dispatch ios swift

我有一个使用 Alamofire 发出多个 HTTP 请求的函数。我想等待所有这些都完成才能返回一个值。但是,它卡在了dispatch.wait()处

class func getActionField(fieldid: String, completion: @escaping (_ res: [String: [Double]]) -> Void) {
        var resreturn: [String: [Double]] = ["temperature":[], "humidity":[], "ph":[], "light":[]]
        let dispatch = DispatchGroup()
        dispatch.enter()
        Alamofire.request(url + "aktionsdaten/temperatur/" + fieldid, method: .get).responseJSON{ response in
            resreturn["temperature"] = response.result.value as! NSArray as? [Double] ?? [0.0,0.0]
            dispatch.leave()
        }
        dispatch.enter()
        Alamofire.request(url + "aktionsdaten/light/" + fieldid, method: .get).responseJSON{ response in
            resreturn["light"] = response.result.value as! NSArray as? [Double] ?? [0.0,0.0]
            dispatch.leave()
        }
        dispatch.enter()
        Alamofire.request(url + "aktionsdaten/ph/" + fieldid, method: .get).responseJSON{ response in
            resreturn["ph"] = response.result.value as! NSArray as? [Double] ?? [0.0,0.0]
            dispatch.leave()
        }
        dispatch.enter()
        Alamofire.request(url + "aktionsdaten/feuchtigkeit/" + fieldid, method: .get).responseJSON{ response in
            resreturn["humidity"] = response.result.value as! NSArray as? [Double] ?? [0.0,0.0]
            dispatch.leave()
        }
        dispatch.wait()
        completion(resreturn)
    }
Run Code Online (Sandbox Code Playgroud)

rma*_*ddy 6

假设getActionField正在主队列上调用它,并且了解 Alamofire 在主队列上调用其完成块(我认为设计不好),那么您将陷入死锁,因为对的调用wait现在正在阻塞主队列,并且没有任何leave可以拨打电话。

您绝不能使用同一个线程来调用waitleave

最简单的解决方案是将 的使用替换waitnotify

group.notify(queue: DispatchQueue.main) {
    completion(resreturn)
}
Run Code Online (Sandbox Code Playgroud)

wait一般而言,您应该避免使用。特别是如果您已经在使用完成处理程序并且该方法不需要等待。