【Swift】deinitではwillSet/didSetが呼ばれないというお話
結論
init/deinit内でプロパティに代入を行っても、willSet/didSetは呼ばれないので注意しましょう。
ただし、スーパークラスのプロパティのwillSet/didSetは呼ばれるようです。
公式ガイドの注意書き
公式ガイド(The Swift Programming LanguageのProperties)に、以下のような注意書きがあります。
NOTE
The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. They are not called while a class is setting its own properties, before the superclass initializer has been called.1注意
サブクラスのイニシャライザ内で、スーパークラスのイニシャライザが呼ばれた後に、プロパティがセットされたとき、スーパークラスのプロパティのwillSetとdidSetのオブザーバーが呼ばれます。スーパークラスのイニシャライザが呼ばれる以前に、自身のプロパティをセットしている間は呼ばれません。2
なるほど。スーパークラスのプロパティのdidSet/willSetについては、サブクラス内のイニシャライザでスーパクラスのイニシャライザを呼んだ後であれば、機能するということらしいです。
クラス自身で定義したプロパティのdidSet/willSetについては、イニシャライザで呼ばれないのは当然だろということか、記述が見当たりませんでした。
コードで確認
確かにスーパークラスのプロパティのdidSetについては呼ばれました。
class Animal {
var age: Int {
didSet {
print(#function, age, oldValue)
}
}
init(age: Int) {
self.age = age // -> 呼ばれない
}
}
class Tiger: Animal {
var family: String {
didSet {
print(#function, family, oldValue)
}
}
init(age: Int, family: String) {
self.family = family // -> 呼ばれない
super.init(age: age) // -> 呼ばれない
self.age += 0 // -> didSetが呼ばれる!!
self.family += "" // -> 呼ばれない
}
deinit {
print(#function)
age = 0 // -> 呼ばれる
family = "" // -> 呼ばれない
}
}
どういうときに注意すべき?
例えば、Timerをdeinitでinvalidateしたいときに、以下のような書き方をすると呼ばれないので注意しましょう。
class ViewController2: UIViewController {
var timer: Timer? {
willSet {
timer?.invalidate()
}
}
deinit {
timer = nil // nilを代入してもwillSetは呼ばれない!
// -> timer?.invalidate()
}
...
}
参考
Swiftでdeinit時にメンバ変数(property)のdidSetが呼ばれない気がした
Can I use didSet in deinit?
-
[The Swift Programming Language - Properties](https://docs.swift.org/swift-book/LanguageGuide/Properties ↩
-
太字による強調は訳者による ↩
Author And Source
この問題について(【Swift】deinitではwillSet/didSetが呼ばれないというお話), 我々は、より多くの情報をここで見つけました https://qiita.com/turara/items/8302e9bf61eb778e3d9c著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .