如何< BluetoothRFCOMMChannelID>在Swift中打开UnsafeMutablePointer

cedebl8k  于 9个月前  发布在  Swift
关注(0)|答案(1)|浏览(118)

这似乎是Swift初学者的一个常见问题。我读了很多案例,但我没有找到任何解释来解决我的案例。
我正在使用IOBluetooth打开蓝牙串行连接。
我需要使用UnsafeMutablePointer<BluetoothRFCOMMChannelId>
我把它设置成这样

var rfcommChannel: IOBluetoothRFCOMMChannel? = nil
var rfcommChannelID: BluetoothRFCOMMChannelID? = nil
let channelIdResult = service?.getRFCOMMChannelID(&rfcommChannelID)

if channelIdResult != kIOReturnSuccess {
   print("Failed to get RFCOMM channel ID: \(String(describing: channelIdResult))")
    return
}
        
print(rfcommChannelID as Any) // Optional(2)
_ = device?.openRFCOMMChannelAsync(&rfcommChannel, withChannelID: rfcommChannelID!, delegate: self)

字符串
应用程序崩溃,

Fatal error: Unexpectedly found nil while unwrapping an Optional value


我已经尝试

if let rfcommChannelID = rfcommChannelID {
   _ = device?.openRFCOMMChannelAsync(&rfcommChannel, withChannelID: rfcommChannelID, delegate: self)
} else {
   print("failed for some reason")
}


它总是因为某种原因失败。我错过了什么?如果我硬编码id,它就可以工作,但这并没有真正帮助
我可以看到调试器中的值不是nil,但是每个测试使用都考虑值nil,甚至打印到控制台也会打印optional(2),这是正确的值

rjee0c15

rjee0c151#

此代码不正确:

var rfcommChannelID: BluetoothRFCOMMChannelID? = nil
let channelIdResult = service?.getRFCOMMChannelID(&rfcommChannelID)

字符串
getRFCOMMChannelID()接受指向BluetoothRFCOMMChannelID的指针,而不是指向BluetoothRFCOMMChannelID?的指针。此类型实际上只是UInt8的类型别名。UInt8UInt8?的大小不同(第一个是1字节;第二个是2字节)。因此,getRFCOMMENELID更新了两个字节值的第一个字节,并破坏了数据结构。
你的意思是:

var rfcommChannelID: BluetoothRFCOMMChannelID = 0


rfcommChannel设置为Optional是正确的,因为这是openRFCOMMChannelAsync所接受的。
为什么编译器没有捕捉到这个错误?老实说,我不完全确定。这可能是一个编译器bug。我仍然在思考是否有特别方便的情况,这是允许与现有C代码兼容的。(IOBluetooth没有为Swift进行空性审计。我不确定这是否重要,但它可能与bug有关。)

相关问题