Swift定数ivarを持つクラス(インスタンス定数と呼ばれていますか?)があります。値をこの定数に設定するには、目的のオブジェクトの初期化子を呼び出し、それ自体を渡す必要がありますただし、最初にすべての値を初期化してから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()
}
}
残念ながら、bluetoothManager
を定数として使用することはできなくなったようです。 Swift 1.2から始まり、イニシャライザでは、定数プロパティは値を1回しか割り当てることができません。これにより、オプションとして宣言して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()
の後に値を割り当てることができます。
_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)
}
}
_
bluetoothManager
はオプションであるため、super.init()
が呼び出されるまでに、すべてのプロパティが初期化されます(bluetoothManager
はnil
で暗黙的に初期化されます)。ただし、クラスが初期化された後はbluetoothManager
が確実に値を持つことがわかっているため、使用時のチェックを回避するために、明示的にアンラップされたものとして宣言します。
更新
プロパティは定数として宣言でき、初期化子で変更できます。初期化が完了するまでに、値が明確であることを確認する必要があります。これは、Swiftブックの「初期化中の定数プロパティの変更」の章に記載されています。
まだ完全に初期化されていないオブジェクトからselfを渡す必要がある呼び出しでプロパティを初期化する必要がある状況については、「所有されていない参照と暗黙的にアンラップされたオプションプロパティ」の章で説明します。
BluetoothManagerを@lazy
プロパティを使用して、後でアクセスします。 startAdvertising
?
@lazy var bluetoothManager: CBPeripheralManager = CBPeripheralManager(delegate: self, queue: nil)
init() { ... }
func start() {
self.bluetoothManager.startAdvertising([ "foo" : "bar" ])
}