我正在将一个Objective-c代码转换为swift,它编译得很完美但在运行时给了我错误。它说:
致命错误:在解包可选值时意外发现nil
为什么?代码以objective-c格式完美运行。
swift版本:
@IBAction func conn(sender: UIButton) {
if self.ble.CM.state != CBCentralManagerState.PoweredOn{
}
if self.ble.peripherals.count == 0 {
self.ble.findBLEPeripherals(2)
}
else {
if !(self.ble.activePeripheral != nil) {
self.ble.connectPeripheral(self.ble.peripherals.objectAtIndex(0) as! CBPeripheral)
}
}
btnScan.enabled = false
indConnecting.startAnimating()
}
此行在运行时抛出错误:
if self.ble.peripherals.count == 0
objective-c version:
- (void) tryToConnectToBLEShield {
//Check core bluetooth state
if (self.ble.CM.state != CBCentralManagerStatePoweredOn)
//Check if any periphrals
if (self.ble.peripherals.count == 0)
[self.ble findBLEPeripherals:2.0];
else
if (! self.ble.activePeripheral)
[self.ble connectPeripheral:[self.ble.peripherals objectAtIndex:0]];
}
实际发生了什么?
答案 0 :(得分:1)
我对这个库并不熟悉,但根据你的评论说明peripherals
是“肯定的”隐式解包的可选项,你会想要这样的东西:
if (self.ble.peripherals?.count ?? 0) == 0 {
self.ble.findPeripherals(2)
}
我们仍然可以使用可选的绑定&即使使用隐式解包的选项也可以解开技巧。
所以,首先我们使用可选的unwrap来获取计数:
self.ble.peripherals?.count
如果count
为非peripherals
,则会返回peripherals
nil
,或者安全返回nil
。
接下来,我们讨论Nil Coalescing Operator:
self.ble.peripherals?.count ?? 0
因此,只要左半部分返回nil
,我们就会使用0
。
现在我们将您与0
进行比较,正如您尝试的那样:
(self.ble?.peripherals?.count ?? 0) == 0
当true
为count
或0
为peripherals
时,会返回nil
。最终这是Objective-C代码的确切行为,因为对Objective-C的方法调用返回NULL
/ NO
/ 0
(当{时返回YES
{1}} - 与==
进行比较。