storyboardのオブジェクトをコードに関連づけるとき、 @IBOutlet weak var hogehoge: UIView!
みたいなコードが自動生成される。
ただ、weak
はいらないだの、!
を?
にした方がいいなど議論があるので、それについて検証した。
解放されるか確認するために、こんなViewで検証を行った。
class HogeView: UIView {
deinit {
print ("deinit!!!!")
}
}
@IBOutlet weak var hogehoge: HogeView!
について
@IBOutlet var hogehoge: HogeView?
viewDidLoad() {
super.viewDidLoad()
hogehoge.removeFromSuperview()
}
上記のコードだけでdeinitが呼ばれる、つまりsuper viewからremoveされたらもうそのviewが使えなくなる。
使おうとしようものなら、クラッシュが発生する、怖い
@IBOutlet var hogehoge: HogeView!
について
@IBOutlet var hogehoge: HogeView?
viewDidLoad() {
super.viewDidLoad()
hogehoge.removeFromSuperview()
hogehoge = nil
}
nilを入れて初めてdeinitされる。逆にいうと、removeしてもインスタンスが解放されないので使い回せるので便利。
ただ、removeする前にhogehoge = nil
を入れても、ViewController.view.subviews
が参照しているので、インスタンスは解放されないので注意。
@IBOutlet weak var hogehoge: HogeView?
について
最初のコードと挙動は同じだが、使おうとしてもクラッシュはしないので安全。
安全、かつインスタンスも解放されやすいので、これが最もおすすめ
結論
やっぱりケースバイケースで使うべき。
- IBOutletのViewをremoveする予定がなければ、適当でOK
- IBOutletのViewをremoveし、その後は使わなければ、
@IBOutlet weak var hogehoge: HogeView!
- IBOutletのViewをremoveし、その後また使うなら
@IBOutlet var hogehoge: HogeView!
- なにも予想できない場合は、
@IBOutlet weak var hogehoge: HogeView?
という感じになるのかな。新たな知見がある場合はコメントください。
おまけ
やっぱりprivateつけたいよね
@IBOutlet private weak var hogehoge: HogeView?