Ios 如何在不阻塞代码的情况下等待BLE回调
我正在尝试在两台可编程设备之间交换数据。实际上客户端是正常的,我的问题是IOS手机的服务器端。 我创建了一个从NSObject和CBPeripheralManagerDelegate继承的BluetoothController。服务、广告、连接、订阅和Ios 如何在不阻塞代码的情况下等待BLE回调,ios,swift,multithreading,bluetooth-lowenergy,Ios,Swift,Multithreading,Bluetooth Lowenergy,我正在尝试在两台可编程设备之间交换数据。实际上客户端是正常的,我的问题是IOS手机的服务器端。 我创建了一个从NSObject和CBPeripheralManagerDelegate继承的BluetoothController。服务、广告、连接、订阅和didReceiveWrite作品的所有部分 我的问题是,当我同时调用CBPeripheralManager类的updateValue方法两次或更多次时,只有第一次调用成功。在Swift文档中,如果发送队列正忙,此函数将返回false。 我编写了这
didReceiveWrite
作品的所有部分
我的问题是,当我同时调用CBPeripheralManager类的updateValue方法两次或更多次时,只有第一次调用成功。在Swift文档中,如果发送队列正忙,此函数将返回false。
我编写了这样一个伪无限循环
while !peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil) {}
它可以工作,但它是一个非常糟糕的实现
所以在那之后,我尝试使用DispatchSemaphore
let semaphore = DispatchSemaphore(value: 1)
func write(_ data: Data) {
DispatchQueue.global().async {
self.semaphore.wait()
self.peripheralManager.updateValue(data,
for: self.messageContentCharacteristic,
onSubscribedCentrals: nil)
}
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
semaphore.signal()
}
所有线程都在运行。第一个调用updateValue
,我的客户机收到通知。另一个正在等待。
但是,永远不会调用“PeripheralManagersReady”#toUpdateSubscribers回调,并且我的应用程序会被阻塞
我尝试使用不同的方法处理具有其他优先级的DispatchGroup和DispatchQueue,但我的问题仍然是一样的
我希望有人能帮助我成为一名更好的开发人员:)正如Paulw11所说,我实现了一个基于Swift算法俱乐部的通用队列。我使用信号灯,但只用于线程安全
let queue = Queue<Data>()
let semaphore = DispatchSemaphore(value: 1)
func write(_ data: Data) {
if !peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil) {
semaphore.wait()
queue.enqueue(data)
semaphore.signal()
}
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
if !queue.isEmpty {
semaphore.wait()
if let data = queue.dequeue() {
peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil)
}
semaphore.signal()
}
}
let queue=queue()
让信号量=分派信号量(值:1)
func写入(u数据:数据){
if!peripheralManager.updateValue(数据、,
对于:messageContentCharacteristic,
已订阅中心:无){
信号量。等待()
queue.enqueue(数据)
信号量
}
}
func外围设备管理器就绪(toUpdateSubscribers外围设备:CBPeripheralManager){
如果!queue.isEmpty{
信号量。等待()
如果let data=queue.dequeue(){
peripheralManager.updateValue(数据、,
对于:messageContentCharacteristic,
已订阅中心:无)
}
信号量
}
}
正如Paulw11所说,我实现了一个基于Swift算法的通用队列。我使用信号灯,但只用于线程安全
let queue = Queue<Data>()
let semaphore = DispatchSemaphore(value: 1)
func write(_ data: Data) {
if !peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil) {
semaphore.wait()
queue.enqueue(data)
semaphore.signal()
}
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
if !queue.isEmpty {
semaphore.wait()
if let data = queue.dequeue() {
peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil)
}
semaphore.signal()
}
}
let queue=queue()
让信号量=分派信号量(值:1)
func写入(u数据:数据){
if!peripheralManager.updateValue(数据、,
对于:messageContentCharacteristic,
已订阅中心:无){
信号量。等待()
queue.enqueue(数据)
信号量
}
}
func外围设备管理器就绪(toUpdateSubscribers外围设备:CBPeripheralManager){
如果!queue.isEmpty{
信号量。等待()
如果let data=queue.dequeue(){
peripheralManager.updateValue(数据、,
对于:messageContentCharacteristic,
已订阅中心:无)
}
信号量
}
}
不要使用信号量和块。如果在您等待发送第二个更新时必须发送另一个更新,那么即使它起作用,这种方法也不会帮助您。您应该创建一个队列(例如使用数组),如果无法发送数据,则将其添加到队列中。当外围设备管理器指示它准备再次发送时,您开始处理队列。不要使用信号量和阻塞。如果在您等待发送第二个更新时必须发送另一个更新,那么即使它起作用,这种方法也不会帮助您。您应该创建一个队列(例如使用数组),如果无法发送数据,则将其添加到队列中。当外围设备管理器指示准备再次发送时,您开始处理队列。