web-dev-qa-db-ja.com

SwiftでNSNotificationのオブザーバーを削除する場所

NSNotificationdealloc()は使用できないため、SwiftのviewDidUnloadのオブザーバーはどこで削除する必要がありますか?

68
Clement Joseph

deallocと同じように機能する以下のメソッドを使用します。

deinit {
    // Release all resources
    // perform the deinitialization
}

初期化解除子は、クラスインスタンスの割り当てが解除される直前に呼び出されます。 initializersがinitキーワードで記述される方法と同様に、deinitキーワードでdeinitializerを記述します。非初期化子はクラス型でのみ使用可能です。

Swift Deinitializer

62
Kampai

iOS 9(およびOS X 10.11)以降、オブザーバーを削除する必要はありませんブロックベースのオブザーバーを使用していない場合は自分で。システムは、可能な場合は観測者にゼロ化弱参照を使用するため、それを行います。

また、ブロックベースのオブザーバーを使用している場合は、クロージャーのキャプチャリストで[weak self]を使用して自分自身を弱くキャプチャし、deinitメソッドのobserverを削除します。自己への弱い参照を使用しない場合、deinitメソッド(したがって、そのオブザーバーの削除)は呼び出されません。これは、Notification Centerが無期限に強力な参照を保持するためです。

詳細については、 OS X v10.11およびiOS 9のFoundationリリースノート を参照してください。

オブザーバーをゼロ化弱参照として保存できる場合、基盤となるストレージはオブザーバーをゼロ化弱参照として保存します。代わりに、オブジェクトを弱く保存できない場合(つまり、ランタイムを妨げるカスタムの保持/解放メカニズムがあります)オブジェクトを弱く格納できることから)、オブジェクトを非ゼロのゼロ化参照として格納します。これは、オブザーバが割り当て解除メソッドで登録解除する必要がないことを意味します。

NS.

105

次の3つの方法を使用できます。

1-popViewControllerの後、戻るnavigationControllerまたはdismissViewControllerAnimated

deinit {
        print("Remove NotificationCenter Deinit")
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

または

2-viewDidDisappear、次のView Controllerになった後に削除します:

override func viewDidDisappear(animated: Bool) {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

または

3-viewWillDisappear-次のビューを開く前:

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

Swift 3.0構文:

NotificationCenter.default.removeObserver(self)
49
Pablo Ruan

Swift 4.2では、これはオブザーバーを削除する方法の1つです

deinit {
    NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}

viewDidLoadクラスでaddObserver通知を設定します

override func viewDidLoad() {
    super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}
9
Ashim Dahal

Swiftには、クラスのインスタンスが破棄される前に呼び出されるdeinitメソッドが用意されています。

https://developer.Apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

3
pmick

また、この方法を使用する必要があることも指摘しておきます。

func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)

の代わりに

func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol

後者はオブザーバーを削除しません(最近この問題に遭遇しました)。前者は、iOS9を使用している場合、オブザーバーを削除します。

2
Guy Daher

viewWillAppear()にオブザーバーを追加し、viewWillDisappear()でオブザーバーを削除することも有効です。

0
mayank khare