Где я должен удалить наблюдателя 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()