Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在不阻塞代码的情况下等待BLE回调_Ios_Swift_Multithreading_Bluetooth Lowenergy - Fatal编程技术网

Ios 如何在不阻塞代码的情况下等待BLE回调

Ios 如何在不阻塞代码的情况下等待BLE回调,ios,swift,multithreading,bluetooth-lowenergy,Ios,Swift,Multithreading,Bluetooth Lowenergy,我正在尝试在两台可编程设备之间交换数据。实际上客户端是正常的,我的问题是IOS手机的服务器端。 我创建了一个从NSObject和CBPeripheralManagerDelegate继承的BluetoothController。服务、广告、连接、订阅和didReceiveWrite作品的所有部分 我的问题是,当我同时调用CBPeripheralManager类的updateValue方法两次或更多次时,只有第一次调用成功。在Swift文档中,如果发送队列正忙,此函数将返回false。 我编写了这

我正在尝试在两台可编程设备之间交换数据。实际上客户端是正常的,我的问题是IOS手机的服务器端。 我创建了一个从NSObject和CBPeripheralManagerDelegate继承的BluetoothController。服务、广告、连接、订阅和
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,
已订阅中心:无)
}
信号量
}
}

不要使用信号量和块。如果在您等待发送第二个更新时必须发送另一个更新,那么即使它起作用,这种方法也不会帮助您。您应该创建一个队列(例如使用数组),如果无法发送数据,则将其添加到队列中。当外围设备管理器指示它准备再次发送时,您开始处理队列。不要使用信号量和阻塞。如果在您等待发送第二个更新时必须发送另一个更新,那么即使它起作用,这种方法也不会帮助您。您应该创建一个队列(例如使用数组),如果无法发送数据,则将其添加到队列中。当外围设备管理器指示准备再次发送时,您开始处理队列。