Где я должен удалить наблюдателя NSNotificationв Swift, поскольку viewDidUnloadи dealloc()недоступны?
Где я должен удалить наблюдателя NSNotificationв Swift, поскольку viewDidUnloadи dealloc()недоступны?
Ответы:
Используйте метод ниже, который работает так же, как dealloc.
deinit {
// Release all resources
// perform the deinitialization
}
Деинициализатор вызывается непосредственно перед освобождением экземпляра класса. Вы пишете деинициализаторы с ключевым словом deinit, аналогично тому, как инициализаторы пишутся с ключевым словом init. Деинициализаторы доступны только для типов классов.
deinitМетод @Kampai для ViewControllerA не будет вызываться, когда он отправит ViewControllerB.
deinitдля ViewControllerA будет вызываться только тогда, когда его нет в стеке контроллера навигации. Например: переключение на rootViewController (если rootViewController не ViewControllerA)
deinit. Идеальное место для звонкаfunc viewDidDisappear(_ animated: Bool)
Начиная с iOS 9 (и OS X 10.11), вам не нужно удалять наблюдателей. самостоятельно, если вы не используете наблюдателей на основе блоков. Система сделает это за вас, поскольку использует слабые обнуления для наблюдателей там, где это возможно.
И если вы используете наблюдателей на основе блоков, убедитесь, что вы слабо захватываете себя, используя [weak self]в списке захвата закрытия, и удалите наблюдателя в deinitметоде. Если вы не используете слабую ссылку на себя, deinitметод (и, следовательно, удаление этого наблюдателя) никогда не будет вызван, поскольку Центр уведомлений будет хранить сильную ссылку на него неопределенно долго.
Дополнительную информацию можно найти в Примечаниях к выпуску Foundation для OS X v10.11 и iOS 9 .
Если наблюдатель может быть сохранен как слабая обнуляемая ссылка, базовое хранилище сохранит наблюдателя как обнуляемую слабую ссылку, в качестве альтернативы, если объект не может быть сохранен в слабом режиме (т.е. он имеет настраиваемый механизм сохранения / освобождения, который предотвратит выполнение из-за возможности слабого хранения объекта) он сохранит объект как неслабую ссылку обнуления. Это означает, что наблюдатели не обязаны отменять регистрацию в их методе освобождения.
Наблюдатели на основе блоков с помощью метода - [NSNotificationCenter addObserverForName: object: queue: usingBlock] по-прежнему необходимо отменить регистрацию, когда они больше не используются, поскольку система по-прежнему имеет сильную ссылку на этих наблюдателей.
delegate = nilв dealloc()методе. Теперь он работает так же?
Вы можете использовать три метода:
после popViewController, назад navigationControllerили dismissViewControllerAnimated:
deinit {
print("Remove NotificationCenter Deinit")
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewDidDisappear, удалите после того, как это уже следующий контроллер представления:
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewWillDisappear - перед открытием следующего вида:
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Синтаксис Swift 3.0:
NotificationCenter.default.removeObserver(self)
В 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)
}
Swift предоставляет метод deinit, который вызывается для экземпляров классов перед их уничтожением.
Также хочу отметить, что вам следует использовать этот метод:
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.
deallocметоде.
deinit {
NotificationCenter.default.removeObserver(self)
}
Swift 5
У меня есть приложение для чата, поэтому всякий раз, когда я перехожу из своего ChatLogViewController к другому viewController, а затем возвращаюсь, у меня есть 1 дополнительный наблюдатель моего уведомления с клавиатуры. Чтобы удалить это, я удаляю всех наблюдателей, когда меняю свой viewController или исчезаю из моего chatLogViewController .
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
Также хорошо, если вы добавите своего наблюдателя viewWillAppear()и удалите их вviewWillDisappear()