有什么好的方法初始化CBCentralManager的实例,该实例需要一个委托并且通常指向拥有类?

我可以将属性声明为一个隐式解包的可选属性,但按照一般惯例,这样做似乎并不像Swift一样,也不是很安全。

另外,我可以将属性声明为可选。但是,由于CBCentralManager的初始化程序未声明为可失败的,因此这样声明实例似乎没有任何意义。

隐式展开可选:

class MyUnwrappedOptional: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager!

    func init() {
        super.init()

        centralManager = CBCentralManager(delegate: self, queue: nil, options:nil)

        // Subsequent usages of centralManager in other methods of this class don't require additional unwrapping.
        centralManager.scanForPeripheralsWithServices(services, options: nil)
    }
}


使用可选:

class MyOptionalClass: NSObject, CBCentralManagerDelegate {
    var centralManager: CBCentralManager?

    func init() {
        super.init()

        centralManager = CBCentralManager(delegate: self, queue: nil, options:nil)

        // Subsequent usages of centralManager in other methods of this class require optional checks:
        if let central = centralManager {
            central.scanForPeripheralsWithServices(services, options: nil)
        }

        // :: or ::
        central!.scanForPeripheralsWithServices(services, options: nil)
    }
}


这些是更优选的还是实现这一目标的另一种方法?

最佳答案

在初始化每个没有默认值且不是可选的(默认值为self的)非init属性之前,无法在lazy方法中使用nil

如果您总是在centralManager中初始化init,并且没有可能使其成为nil的代码,那么我想说CBCentralManager!声明是一个不错的选择。这是隐式展开的可选类型的主要目的之一。

以下是the documentation about implicitly unwrapped optionals的摘录:


有时,从程序的结构中可以明显看出,可选的
首次设置该值后,始终会有一个值。在这些情况下,
有助于消除检查和拆开可选值的需要
每次访问它,因为可以安全地假定它具有一个
一直珍视。

这些可选类型定义为隐式解包
可选的。您可以通过放置一个
感叹号(String!)而不是问号(String?)
您要使其为可选的类型。


如果程序逻辑确实允许在某些时候使用nil。然后,正常的可选类型是适当的选择。

另一种可能的选择是让您将centralManager属性声明为a lazy property。如果执行此操作,则只有在访问它后才能创建它,但是您可以引用self并将其设为非可选。当需要使用它时,将决定是否使用此选项。

lazy var centralManager: CBCentralManager = { [unowned self] () -> CBCentralManager in
    CBCentralManager.init(delegate: self, queue: nil, options: [:])
}()

07-28 01:37
查看更多