Подтвердить что ты не робот

Где удалить наблюдателя для NSNotification в Свифт?

Где я должен удалить наблюдателя для NSNotification в Swift, так как viewDidUnload и dealloc() недоступны?

4b9b3361

Ответ 1

Используйте метод ниже, который функционирует так же, как dealloc.

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

Деинициализатор вызывается непосредственно перед освобождением экземпляра класса. Вы пишете деинициализаторы с ключевым словом deinit, подобно тому, как инициализаторы пишутся с ключевым словом init. Деинициализаторы доступны только для типов классов.

Swift Deinitializer

Ответ 2

Начиная с iOS 9 (и OS X 10.11), вам не нужно удалять наблюдателей самостоятельно, хотя вы не используете блочные наблюдатели. Система сделает это за вас, поскольку она использует нулевые ссылки для наблюдателей, где это возможно.

И если вы используете наблюдателей на основе блоков, убедитесь, что вы слабо фиксируете себя, используя [weak self] в списке захвата замыканий, и удаляете наблюдателя в методе deinit. Если вы не используете слабую ссылку на себя, метод deinit (и, следовательно, удаление этого наблюдателя) никогда не будет вызван, так как Центр уведомлений будет хранить сильную ссылку на него бесконечно.

Дополнительная информация может быть найдена в Основных примечаниях к выпуску для OS X v10.11 и iOS 9.

Если наблюдатель может быть сохранен как ссылка со слабой нулевой привязкой, основное хранилище будет хранить наблюдатель как слабую ссылку при нулевой настройке, или, если объект не может быть сохранен как слабый (т.е. У него есть собственный механизм сохранения/освобождения, который предотвращает время выполнения) из-за способности хранить объект слабо) он будет хранить объект как неслабую нулевую ссылку. Это означает, что наблюдатели не обязаны отменять регистрацию в своем методе освобождения.

Наблюдатели на основе блоков с помощью метода - [NSNotificationCenter addObserverForName: object: queue: usingBlock] все еще должны быть незарегистрированными, когда они больше не используются, поскольку система по-прежнему имеет сильную ссылку на этих наблюдателей.

Ответ 3

Вы можете использовать три метода:

1 - после popViewController, назад navigationController или dismissViewControllerAnimated:

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

или

2 - viewDidDisappear, удалить после того, как он уже является следующим контроллером представления:

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)

Ответ 5

Я также хочу указать, что вы должны использовать этот метод:

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.

Ответ 6

Также хорошо, если вы добавите своего наблюдателя в viewWillAppear() и удалите их в viewWillDisappear()

Ответ 7

// For Swift 4.2//

override func viewWillDisappear (_ animated: Bool) 
{

    NotificationCenter.default.removeObserver(self)

}

Ответ 8

В Swift 4.2 это один из способов удаления наблюдателя.

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

Настройка addObserver в классе viewDidLoad

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