我有一个Swift类有一个常量ivar(他们现在称为实例常量?)。要将值设置为此常量,我需要调用所需对象的初始化器并传递自身。但是,我不允许,因为我需要首先初始化所有的值,然后调用super.init(),然后我被允许访问自我。那么在这种情况下做什么?
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() } }
Swift 1.2和更高版本的UPDATE
不幸的是,似乎不可能有蓝牙管理器作为一个常数。从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,options: options) } }
原答案
你可以在这里使用隐式解包的可选(对于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,options: options) } }
因为bluetoothManager是可选的,在调用super.init()时,所有属性都被初始化(bluetoothManager是用nil隐式初始化的)。但是因为我们知道bluetoothManager在类初始化之后肯定会有值,所以我们将它声明为显式解包,以避免在使用它时进行检查。
更新
属性可以声明为常量,并且在初始化器中仍然可以更改。只需要确保它在初始化完成时有一个确定的值。这在Swift书的“修改初始化期间的常量属性”一章中有说明。
当一个属性需要通过一个调用来初始化的时候,这里self必须从尚未完全初始化的对象传递的情况,在“未知的引用和隐含的解包的可选属性”一章中描述。