需要self在init中设置swift类的所有常量
我有一个Swift类,它有一个常量ivar(现在称为实例常量吗?)。要将该值设置为该常量,我需要调用所需对象的初始值设定项并传递它自己。但是,我不允许这样做,因为我需要先初始化所有值,然后调用需要self在init中设置swift类的所有常量,swift,self,initializer,Swift,Self,Initializer,我有一个Swift类,它有一个常量ivar(现在称为实例常量吗?)。要将该值设置为该常量,我需要调用所需对象的初始值设定项并传递它自己。但是,我不允许这样做,因为我需要先初始化所有值,然后调用super.init(),然后才允许访问self。那么在这种情况下该怎么办呢 class Broadcaster: NSObject, CBPeripheralManagerDelegate { let broadcastID: NSUUID let bluetoothManager: C
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()
}
}
类广播者:NSObject、CBPeripheralManagerDelegate{
让广播ID:nsuid
让bluetoothManager:CBPeripheralManager
初始化(广播ID:NSUID){
self.broadcastID=broadcastID
let选项:Dictionary=[CBPeripheralManagerProptionShowPowerAlertKey:true]
self.bluetoothManager=cbperipheraldmanager(委托:self,队列:nil,选项:options)//在super.init调用之前使用了错误:“self”
super.init()
}
}
将您的bluetoothManager设置为一个@lazy
属性,并在以后访问它,例如开始转换
@lazy var bluetoothManager: CBPeripheralManager = CBPeripheralManager(delegate: self, queue: nil)
init() { ... }
func start() {
self.bluetoothManager.startAdvertising([ "foo" : "bar" ])
}
更新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)
}
}
由于bluetoothManager
是可选的,因此在调用super.init()
时,所有属性都会初始化(bluetoothManager
隐式初始化为nil
)。但是因为我们知道bluetoothManager
在类初始化后肯定会有该值,所以我们将其声明为显式未包装,以避免在使用它时进行检查
更新
属性可以声明为常量,但仍可以在初始值设定项中更改。我们只需要确保在初始化完成时它有一个确定的值。这在Swift手册的“初始化期间修改常量属性”一章中有记录
“无主引用和隐式展开可选属性”一章中描述了需要使用调用初始化属性的情况,其中必须从尚未完全初始化的对象传递self。这是我已经尝试过的。它是有效的。但是,这就失去了出租汽车的好处/但是它需要是一个var,而不是let,不是吗?不,因为这一切都发生在初始值设定项中,它仍然可以是let。但是在类初始化之后,将无法更改它。请参阅Swift book中名为“在初始化期间修改常量属性”和“无主引用和隐式展开可选属性”的部分。老实说,在初始化super之前,需要初始化自己的实例变量,这似乎没有多大意义。super对我的实例变量一无所知。那么,背后的理由是什么?反之亦然,这对我来说更有意义。@eofster,你的答案的两部分在当前版本中都不起作用。
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)
}
}