Bezpieczne usuwanie obserwatorów
Unikanie wycieków i awarii powodowanych przez nieaktualnych obserwatorów.
Bezpieczne usuwanie obserwatorów to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Bezpieczne usuwanie obserwatorów
Obserwatorów należy usuwać, gdy nie są już potrzebni. Pozostawiony obserwator może zareagować po usunięciu swojego właściciela, powodując błędy lub, w przypadku starszych interfejsów API, awarie.
Dlaczego usuwanie ma znaczenie
Obserwatory oparte na selektorach musiały dawniej być usuwane w deinit, aby uniknąć wysłania komunikatu do zwolnionego obiektu.
import Foundation
class Watcher: NSObject {
override init() { super.init() }
deinit { NotificationCenter.default.removeObserver(self) }
}
print("Removes itself on deinit")removeObserver(self)
Wywołanie removeObserver(self) wyrejestrowuje jednym wywołaniem wszystkie obserwacje utworzone przez dany obiekt.
import Foundation
class VM: NSObject {
func stop() { NotificationCenter.default.removeObserver(self) }
}
VM().stop()
print("Removed all observations for self")Usuwanie określonej nazwy
Możesz usunąć tylko jedną obserwację, przekazując nazwę i obiekt, a pozostałe pozostawić bez zmian.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
let name = Notification.Name("ping")
center.removeObserver(obj, name: name, object: nil)
print("Removed a specific observation")Obserwatory oparte na tokenie
Oparte na domknięciu addObserver zwraca nieprzezroczysty token. Zachowaj go, a następnie usuń obserwator za pomocą tego tokenu.
import Foundation
let center = NotificationCenter.default
let name = Notification.Name("ping")
let token = center.addObserver(forName: name, object: nil, queue: nil) { _ in }
center.removeObserver(token)
print("Removed via token")Przechowywanie tokenu
Przechowuj token we właściwości, aby żył tak długo, jak długo potrzebujesz obserwacji, i usuń go, gdy przestanie być potrzebny.
import Foundation
class Model {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { _ in }
}
func stop() {
if let t = token { NotificationCenter.default.removeObserver(t) }
}
}
let m = Model(); m.start(); m.stop()
print("Lifecycle managed")Automatyczne czyszczenie za pomocą deinit
Usuń token w deinit, aby obserwacja zakończyła się po dealokacji właściciela.
import Foundation
class Owner {
var token: NSObjectProtocol?
deinit { if let t = token { NotificationCenter.default.removeObserver(t) } }
}
print("Token removed on deinit")Uwaga dotycząca współczesnego cyklu życia
W nowszych środowiskach wykonawczych obserwatory dodane za pomocą API opartego na bloku są usuwane automatycznie po dealokacji tokenu, ale jawne usuwanie nadal jest bezpieczniejszym i bardziej przejrzystym wyborem.
import Foundation
// Holding the token in a property controls its lifetime.
class C { var token: NSObjectProtocol? }
print("Token lifetime equals observation lifetime")Unikanie cykli silnych odwołań
Jeśli obserwator w postaci domknięcia silnie przechwytuje self, użyj [weak self], aby uniknąć cyklu silnych odwołań uniemożliwiającego dealokację.
import Foundation
class VM {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { [weak self] _ in
self?.handle()
}
}
func handle() { print("handled") }
}
VM().start()Podwójne usunięcie jest bezpieczne
Usunięcie obserwatora, który został już usunięty, jest nieszkodliwe, więc defensywne czyszczenie nie spowoduje awarii.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
center.removeObserver(obj)
center.removeObserver(obj) // no harm
print("Safe to remove twice")Podsumowanie dobrych praktyk
Preferuj domknięcia oparte na tokenach, przechowuj token, usuwaj go w deinit i przechwytuj self słabo. Dzięki temu cykle życia obserwacji pozostają prawidłowe.
import Foundation
class Best {
var token: NSObjectProtocol?
deinit { token.map { NotificationCenter.default.removeObserver($0) } }
}
print("Followed best practices")Szybkie sprawdzenie
Jak usunąć obserwator oparty na domknięciu, dodany za pomocą addObserver(forName:...)?
Podsumowanie
Zawsze usuwaj obserwatorów, których już nie potrzebujesz. W przypadku obserwatorów opartych na selektorach używaj removeObserver(self), a w przypadku obserwatorów opartych na domknięciach — zwróconego tokenu. Przechowuj token, sprzątaj w deinit i przechwytuj self słabo. Następnie: porównanie wzorca obserwatora z alternatywami.
Często zadawane pytania
Czy lekcja „Bezpieczne usuwanie obserwatorów” jest bezpłatna?
Tak — pełny tekst „Bezpieczne usuwanie obserwatorów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Bezpieczne usuwanie obserwatorów”?
Unikanie wycieków i awarii powodowanych przez nieaktualnych obserwatorów. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Bezpieczne usuwanie obserwatorów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Publikowanie i obserwowanie powiadomień
- Ładunki userInfo powiadomień
- Bezpieczne usuwanie obserwatorów
- Alternatywy dla wzorca Observer