0Pricing
Swift Academy · Lekcja

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

  1. Publikowanie i obserwowanie powiadomień
  2. Ładunki userInfo powiadomień
  3. Bezpieczne usuwanie obserwatorów
  4. Alternatywy dla wzorca Observer
← Powrót do Swift Academy