需要self来在init中设置swift类的所有常量

Mic*_*chs 29 self initializer swift

我有一个具有常量ivar的Swift类(它们现在被称为实例常量吗?).要将值设置为此常量,我需要调用所需对象的初始化程序并传递自身.但是,我不被允许,因为我需要首先初始化所有值,然后调用super.init(),之后我被允许访问self.那么在这种情况下该怎么办?

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    let bluetoothManager: CBPeripheralManager

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID

        let options: Dictionary<NSString, AnyObject> = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options) // error: 'self' used before super.init call

        super.init()
    }
}
Run Code Online (Sandbox Code Playgroud)

eof*_*ter 34

更新Swift 1.2及更高版本

不幸的是,似乎不再可能具有bluetoothManager常数.从Swift 1.2开始,在初始化程序中,常量属性只能赋值一次.这不允许我们nil通过将其声明为可选值并在稍后的初始化过程中更改它来启动值.这是带有bluetoothManager变量的更新版本.

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    var bluetoothManager: CBPeripheralManager!

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID
        super.init()
        let options: Dictionary<String, AnyObject> = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
    }
}
Run Code Online (Sandbox Code Playgroud)

原始答案

您可以在此处使用隐式展开的可选(for bluetoothManager),并在以下情况下为其指定值super.init():

class Broadcaster: NSObject, CBPeripheralManagerDelegate {

    let broadcastID: NSUUID
    let bluetoothManager: CBPeripheralManager!

    init(broadcastID: NSUUID) {
        self.broadcastID = broadcastID
        super.init()
        let options: Dictionary<NSString, AnyObject> = [ CBPeripheralManagerOptionShowPowerAlertKey: true ]
        self.bluetoothManager = CBPeripheralManager(delegate: self, queue: nil, options: options)
    }
}
Run Code Online (Sandbox Code Playgroud)

因为bluetoothManager是可选的,所以super.init()在调用时,所有属性都被初始化(bluetoothManager隐式初始化nil).但是因为我们知道bluetoothManager在初始化类之后肯定会有值,所以我们将它声明为显式解包以避免在使用它时进行检查.

UPDATE

属性可以声明为常量,并且仍然可以在初始化程序中更改.在初始化完成时,必须确保它具有确定的值.这在Swift book的"在初始化期间修改常量属性"一章中有记录.

在需要从尚未完全初始化的对象传递self的调用初始化属性的情况在"无主引用和隐式展开的可选属性"一章中进行了描述.

  • 老实说,在初始化*super之前,需要初始化自己的实例变量似乎没有多大意义.super对我的实例变量一无所知.那背后的理由是什么呢?反之亦然,这对我来说更有意义. (2认同)