当需要一个自我引用时,如何在Swift中初始化CBCentralManager



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

我可以将属性声明为隐式unwrapped可选属性,但这样做似乎不像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)
    }
}

这两种方法中哪一种更受欢迎,还是有其他方法可以实现这一点?

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

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

以下是关于隐式取消包装可选选项的文档摘录:

有时从程序的结构中可以清楚地看出可选的意志总是有一个值,在这个值第一次被设置之后。在这些情况下,它删除检查和展开可选值的需要是否有用每次访问它,因为可以安全地假设它有值。

这些类型的可选被定义为隐式展开可选的。可以编写一个隐式解包裹的可选项感叹号(字符串!)而不是问号(字符串?)可选的类型

如果程序逻辑允许它在可能使用的某个时刻为nil。那么,一个普通的可选类型是合适的选择。

另一个可能的选择是您将centralManager属性声明为lazy属性。如果您这样做,它将不会被创建,直到您访问它,但您将能够引用self并使其成为非可选的。当您需要创建它时,将决定您是否使用此选项。

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

最新更新