Swift

IBOutletにおける weak vs strong

More than 1 year has passed since last update.

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?