Де я повинен видалити спостерігач 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)
}
Також добре, якщо ви додасте свого спостерігача viewWillAppear()
та видалите йогоviewWillDisappear()
Стрімкий 5
У мене є програма для чату, тому, коли я переходжу від свого ChatLogViewController до якогось іншого viewController, а потім повертаюся, у мене є 1 додатковий спостерігач мого сповіщення на клавіатурі. Щоб видалити, я видаляю всіх спостерігачів, коли я зміню мій viewController або зникаю з мого chatLogViewController .
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}