DispatchGroup.wait不等

我正在理解或使用Dispatchgroup。 我已经阅读了很多关于他们的文章,但是大多数的例子/文档都很模糊,或者不像我想要做的,但是每次我提到我的问题时,大家都会说“使用派遣组”。

这是我想要做的(注意:连续命令是CRUCIAL):

  • 发送蓝牙写入特征。
  • 设备收到价值,并吐出一些回应
  • 阅读蓝牙响应(通过读取特性)
  • 发送新的写入特征(不同的命令)
  • 设备收到NEW命令,吐出NEW数据响应

重复两次(总共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 

现在,你可以看到“发送的特征值”是蓝牙function发送时的确认,但是这个输出是在完成整个代码的运行之后创build的,所以基本上它把这些命令放在一些pipe道中,忘了它们做了一切,然后发送的命令,因此我读的回应都是废话! 正如你所看到的,所有接收到的string都是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() } } } 

在你的情况下,你可能有几个select:

首先,如果您知道如果您发送一个命令并准确接收该命令的答案,则可以按以下顺序调用方法:

  1. 调用一个方法来发送命令1

  2. 在接收到对命令1的回答后调用另一种方法

  3. 调用另一种发送命令的方法2

  4. 在获得命令2的答案之后还有一种方法…

ñ。 完成设置

就像我需要注册一个用户一样,我需要首先发送定义的凭证,从服务器获取令牌,然后在其后面运行。

所以你将不得不为每个命令添加一个额外的方法,你会按照命令调用它们

如果你不能识别哪个命令你会得到一个答案,你确定你只发送一个命令,只等待一个答案,那么你可以使用派遣组如下所述:

 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 } } 

让我知道你是否需要更多的细节