[英]DispatchGroup.wait not waiting
我在理解或使用 Dispatchgroup 時遇到問題。 我已經閱讀了很多關於它們的內容,但是大多數示例/文檔都非常模糊或與我想要做的不一樣,但是每次我提到我的問題時,每個人都會說“使用調度組!”。
這是我想要做的(注意:順序是至關重要的):
重復兩次(總共 3 個命令,總共 3 個不同的響應)。
我的代碼:
func tPodInitialSetUp()
{
print ("* * * * * BEGIN SET-UP * * * * *")
let setupDispatchGroup = DispatchGroup()
setupDispatchGroup.enter()
self.writeValue(command: Data(CommandModeCmd)) //231: Put t-Pod in command mode, burst mode is OFF returns OK
setupDispatchGroup.leave()
setupDispatchGroup.wait()
setupDispatchGroup.enter()
deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
print("Sent command 231: returned: \(receivedString1)")
if receivedString1.lowercased() == "ok"
{
print("t-Pod burst mode is OFF")
}
setupDispatchGroup.leave()
setupDispatchGroup.wait()
setupDispatchGroup.enter()
self.writeValue(command: Data(loadProbeCalCmd)) //202: load calibration constants of probe, returns ok or 0
setupDispatchGroup.leave()
setupDispatchGroup.wait()
setupDispatchGroup.enter()
deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
print("Sent command 202: returned: \(receivedString1)")
if receivedString1.lowercased() == "ok"
{
print("Probe Constants loaded")
}
if receivedString1 == "0"
{
print("No probe connected")
}
setupDispatchGroup.leave()
setupDispatchGroup.wait()
setupDispatchGroup.enter()
self.writeValue(command: Data(probeSNCmd)) //205: load probe serial number
setupDispatchGroup.leave()
setupDispatchGroup.wait()
setupDispatchGroup.enter()
deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
print("Sent command 205: returned: \(receivedString1)")
if (receivedString1.count == 6)
{
print("received Probe SN: \(receivedString1)")
probeSN = receivedString1
}
setupDispatchGroup.leave()
setupDispatchGroup.notify(queue: .main)
{
tPodSN = String(describing: connectedDeviceName!.dropFirst(7))
print ("* * * SET-UP COMPLETE * * *")
self.writeValue(command: Data(resetCmd)) //200: resets t-Pod
self.writeValue(command: Data(beaconOffCmd)) //211: turns beacon off (temperature output)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
{
self.dataDisplaySubView.isHidden = false
print ("Adding observers!")
NotificationCenter.default.addObserver(self, selector: #selector(self.updateIncomingData), name: NSNotification.Name(rawValue: DATA_PARSED), object: nil) //Run every time you receive data from BLE
NotificationCenter.default.addObserver(self, selector: #selector(self.calculateTNU), name: NSNotification.Name(rawValue: TOGGLESWITCH_TOGGLED), object: nil) //Run in case the toggle switches change and data needs to be re-calculated
NotificationCenter.default.addObserver(self, selector: #selector(self.parseReceivedData), name: NSNotification.Name(rawValue: DEVICE_FINISHED_SENT_DATA), object: nil) //Run every time you receive the notification that the whole data has been sent
}
}
這將調用具有以下代碼和確認的藍牙寫入命令:
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
guard error == nil else {
print("Error writing descriptor: " + (error?.localizedDescription)!)
return
}
print("Descriptor Value sent")
}
現在,這是我的輸出:
* * * * * BEGIN SET-UP * * * * *
***** WRITING *****
Wrote: 1 bytes
***** WRITING *****
Wrote: 1 bytes
Sent command 231: returned: **T-Pod-9Ch**
***** WRITING *****
Wrote: 1 bytes
Sent command 202: returned: **T-Pod-9Ch**
***** WRITING *****
Wrote: 1 bytes
Sent command 205: returned: **T-Pod-9Ch**
* * * SET-UP COMPLETE * * *
***** WRITING *****
Wrote: 1 bytes
***** WRITING *****
Wrote: 1 bytes
Characteristic Value sent
Adding observers!
Characteristic Value sent
Characteristic Value sent
Characteristic Value sent
Characteristic Value sent
Clearing TNU Array
現在,正如您所看到的,“發送的特征值”是藍牙函數在發送值時給出的確認,但是這個輸出是在運行完整個代碼后創建的,所以基本上它把命令放在某個管道中,忘記了它們做了所有其他的事情,然后發送了命令,因此我正在閱讀的回復都是無稽之談! 正如您所看到的,所有接收到的字符串都是T-Pod-9Ch (這只是它的正常突發輸出),我應該從命令中得到的預期響應是 OK、OK 和 6 位數字(按此順序)。
請幫忙,我已經閱讀了很多次關於調度組應該如何工作的內容,但我就是無法讓他們做我想做的事。
如果我問對了你的問題,你需要在發送新命令之前等待答案。
但是您的寫入沒有完成塊,這就是為什么在您的情況下使用 dispatchGroup 沒有意義。
下面的代碼是使用調度組的常見示例
func someMethod(completionHandler: @escaping ()-> Void) {
//we need to get or set some data in separated queue
DispatchQueue.global(qos: .background).async {
let group = DispatchGroup()
//let's say we have an array of urls and we need to load images and put them to an array
for url in someUrlArray {
group.enter()
SomeLoaderClass.load(url) { image in
//add received image
//leave the group
group.leave()
}
}
//now we need to wait until all images will be downloaded
group.wait()
//then we can finish and call the completion in the main queue
DispatchQueue.main.async {
completionHandler()
}
}
}
在您的情況下,您可能有多種選擇:
首先,如果您知道如果您發送一個命令並收到該命令的正確答案,您可以按以下順序調用方法:
調用一種方法發送命令 1
在收到命令 1 的應答后調用另一種方法
調用另一種方法來發送命令 2
在獲得命令 2 的答案后,還有一種方法......
n. 完成設置
就像我需要注冊一個用戶一樣,我需要先發送定義的憑據,從服務器獲取令牌,然后在它之后運行一些東西。
所以你必須為每個命令添加一個額外的方法,你將根據順序調用它們
如果您無法識別將要獲得響應的命令,並且您確定只發送了一個命令並且只等待了一個響應,那么您可以按照以下描述的方式使用 dispatch group:
typealias Callback = ()->Void
class SomeManagerClass {
var callback: Callback?
func initiateSetup(){
DispatchQueue.global(qos: .background).async { [weak self] in
let group = DispatchGroup()
//now we can send commands
group.enter()
self?.sendCommand(SomeDataForTheFirstCommand) {
//when the first answer will be received, it will init the callback, so you can leave the group now
group.leave()
}
//sending the second command
group.enter()
self?.sendCommand(SomeDataForTheSecondCommand) {
//waiting for the second answer will be received
group.leave()
}
//.... more commands sending same way
group.wait()
//now all commands was send and you got an answer for each
//finishing setup
DispatchQueue.main.async{
self?.finishSetup()
}
}
}
func sendCommand(_ command: Data, callback: Callback?){
self.writeValue(command: command)
self.callback = callback
}
func answerReceived(){
//this is just an example method that is called when you get an answer for any command
//now we can callback
self.callback?()
}
func finishSetup(){
//do something
}
}
如果您需要更多詳細信息,請告訴我
使用 Dispatch 組的示例
private func performTask1() -> String {
print("Task1")
var result: String?
let background = DispatchQueue.global(qos: .background)
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
background.asyncAfter(deadline: .now() + 3) {
result = "Task1 is performed"
dispatchGroup.leave()
}
dispatchGroup.wait()
return result!
}
試試這個來理解 DispactGroup 的概念!
試試吧! 這
leave()所需的DispatchQueue.global(qos: .background )
func dispatchGroup() -> String {
var message = ""
let group = DispatchGroup()
group.enter()
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 5) {
message = "Hiii Friends"
group.leave()
}
group.wait()
return message
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.