swift - returning - Necesito uno mismo para establecer todas las constantes de una clase rápida en init
is swift (2)
ACTUALIZACIÓN para Swift 1.2 y versiones posteriores
Desafortunadamente, parece que ya no es posible tener bluetoothManager
como una constante. A partir de Swift 1.2, en un inicializador, las propiedades constantes solo pueden asignar un valor una vez. Esto no nos permite comenzar con un valor nil
al declararlo como opcional y cambiarlo más adelante en el proceso de inicialización. Aquí está la versión actualizada con bluetoothManager
como una variable.
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)
}
}
Respuesta original
Puede usar implícitamente sin super.init()
opcional aquí (para bluetoothManager
) y asignarle el valor después de 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)
}
}
Como bluetoothManager
es opcional, cuando se llama a super.init()
, todas las propiedades se inicializan ( bluetoothManager
se inicializa implícitamente con nil
). Pero como sabemos que bluetoothManager
definitivamente tendrá el valor después de que se inicialice la clase, lo declaramos explícitamente sin envolver para evitar cheques cuando lo usamos.
ACTUALIZAR
Una propiedad se puede declarar como constante y aún cambiarse en el inicializador. Solo hay que asegurarse de que tiene un valor definido para cuando finalice la inicialización. Esto se documenta en el capítulo "Modificación de propiedades constantes durante la inicialización" del libro Swift.
La situación en la que una propiedad debe inicializarse con una llamada desde la que se debe pasar self desde un objeto aún no completamente inicializado se describe en el capítulo "Referencias sin propiedad y propiedades opcionales implícitamente sin envolver".
Tengo una clase Swift que tiene un ivar constante (¿se llaman constantes de instancia ahora?). Para establecer el valor en esta constante, necesito llamar a un inicializador del objeto deseado y pasarlo. Sin embargo, no se me permite hacerlo, ya que necesito inicializar todos los valores primero, luego llamar a super.init()
y luego se me permite acceder a mí self
. Entonces, ¿qué hacer en este caso?
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()
}
}
¿Qué tal si configura su bluetoothManager como una propiedad de @lazy
y accede a él más adelante, por ejemplo, para startAdvertising
?
@lazy var bluetoothManager: CBPeripheralManager = CBPeripheralManager(delegate: self, queue: nil)
init() { ... }
func start() {
self.bluetoothManager.startAdvertising([ "foo" : "bar" ])
}