CoreBluetooth 中未记录的 API 更改

Undocumented API changes in CoreBluetooth

在Xcode 12.3中,CoreBluetooth.CBService.peripheral在objective-c中定义为:

@property(assign, readonly, nonatomic) CBPeripheral *peripheral;

更新:这是 swift 在 Xcode 12.3 中对上述内容的翻译:

unowned(unsafe) open var peripheral: CBPeripheral { get }

在Xcode 13.0中,CBService.peripheral在swift中定义为:

weak var peripheral: CBPeripheral? { get }

Apple's documentation 表示此 API 自 iOS5 以来一直存在,并且没有任何变化。但是在 Xcode13 中,变量显然是可选的。 (并且它在 Xcode 12.3 中不是可选的,因为它缺少属性 nullable。)

修复相对容易(例如 service.peripheral -> service?.peripheral)- 但它使得无法对 Xcode 12.3 和 13.0 使用相同的代码。我想知道这里是否有我遗漏的细微差别?

可选项是 Swift 的固有部分,而不是 Objective-C 的一部分。 Swift 中的非空引用保证有一个值,而 Objective C 中的任何引用在理论上可以是 null.

引入了 nullablenonnull 装饰器以提高与 Swift 的互操作性,副作用是它们也更清楚地记录了 Objective C APIs .

Core Bluetooth 是 Objective C API,正如您所注意到的,它自 iOS5 以来就可用;在 Swift 和 nullable 装饰器之前。

因此,API 并没有发生太大变化,而是您将 Objective C API 与 Swift [=64= 进行比较] 并且 Apple 尚未将 nullable 装饰器添加到 Core Bluetooth API.

这些 API 都没有改变; CBServiceperipheral 的 Swift 声明 始终 是可选的。 Objective-C 声明 从来没有 nullable null 值一直是可能的。

添加 nullable 不会改变 API 的行为,只是它在 Objective C 中的声明。这可能是 Objective-C 代码的重大更改,或者至少可能导致编译失败,因此 Apple 没有理由更改它并且有充分的理由不更改它。

更新

从您的评论来看,CBService.peripheral 的 Swift 声明确实从 unowned(unsafe) 变为弱可选值确实发生了重大变化。

这是一个更安全的声明,因为在前面的定义中,您有责任检查 peripheral 不是 nil,如果您不这样做,可能会发生崩溃。

在我多年的Core Bluetooth编程中,我认为我从来不需要使用CBService.peripheral,但是,你可以使用基于Swift版本的条件编译来编写适用于 Xcode 13 和更早版本的代码:

var p: CBPeripheral?
#if swift(<5.5) 
    if s.peripheral != nil {
        p = s.peripheral
    }
#else
        p = s.peripheral
#endif