NotificationCenterでオブザーバのインスタンスが破棄されたらオブザーバも破棄されるよね?の確認

f:id:bamboohero:20210529030712p:plain

当たり前の話なんですが、PRレビューをしてたときにふと、「あれ、これってremoveObserverしなくて良いんだっけ?」となったので、動作を確認しました。



動作確認用コードの説明

以下のように2つの画面があります。遷移元のボタンをタップすると遷移先画面が表示されます。

遷移元 遷移先
f:id:bamboohero:20210529025051p:plain:w300 f:id:bamboohero:20210529025133p:plain:w300


遷移先画面の実装はこんな感じです(必要なとこだけ抜粋してます)。

override func viewDidLoad() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(notified(_:)),
        name: UIApplication.didBecomeActiveNotification,
        object: nil)

    button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
}

@objc func notified(_ sender: Any) {
    print("notified")
}

@objc func buttonTapped(_ sender: Any) {
    NotificationCenter.default.removeObserver(
        self,
        name: UIApplication.didBecomeActiveNotification,
        object: nil)
}


アプリがフォアグラウンドになったときにdidBecomeActiveNotificationイベントが通知されるようにオブザーバを設定しています。通知を受けたらコンソールに「notified」と表示されます。

また、「Remove Observer!!」ボタンをタップすると、オブザーバが削除されるようになっています。


動作確認結果

以下の流れで確認しました。

  1. 遷移元のボタンをタップして遷移先画面を表示する
  2. ホーム画面に戻り、再度アプリをフォアグラウンドにする <- ここで「notified」と表示される
  3. 遷移先画面をスワイプダウンして遷移元画面に戻る
  4. ホーム画面に戻り、再度アプリをフォアグラウンドにする <- ここでコンソールには何も表示されない

オブザーバを明示的に削除していませんが、遷移先画面がdismissされると同時にオブザーバも削除されていることがわかります。


また、以下の操作を行うと当然ですがコンソールには何も表示されませんでした。

  1. 遷移元のボタンをタップして遷移先画面を表示する
  2. 「Remove Observer!!」ボタンをタップする
  3. ホーム画面に戻り、再度アプリをフォアグラウンドにする <- ここでコンソールには何も表示されない
  4. 遷移先画面をスワイプダウンして遷移元画面に戻る
  5. ホーム画面に戻り、再度アプリをフォアグラウンドにする <- ここでコンソールには何も表示されない


おわりに

わかりきったことですが、疑問に思ってしまったので念の為確認してみました。

こういうことってありますよね(ない?)