Cykle retencji i ich przerywanie za pomocą weak/unowned
Wykrywajcie cykle retencji między obiektami i closures, a następnie bezpiecznie przerywajcie je za pomocą referencji weak i unowned .
Cykle retencji i ich przerywanie za pomocą weak/unowned to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 3. 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 3 lekcji w sumie.
Czym jest cykl retencji?
Cykl retencji występuje, gdy obiekty (lub domknięcia) przechowują wzajemnie referencje strong, przez co ARC nigdy nie osiąga wartości zero. Cykle należy przerywać za pomocą weak lub unowned.
Cykl obiekt ↔ obiekt
Dwie silne referencje w obu kierunkach tworzą wyciek pamięci: żaden z obiektów nie może osiągnąć wartości zero.
final class Owner {
var gadget: Gadget?
deinit { print("Owner deinit") }
}
final class Gadget {
var owner: Owner?
deinit { print("Gadget deinit") }
}
// Strong ⇄ strong (cycle)
var o: Owner? = Owner()
var g: Gadget? = Gadget()
o!.gadget = g
g!.owner = o
o = nil // no deinit
g = nil // still no deinit (leak)Przerwanie za pomocą weak
Należy oznaczyć jedną stronę jako weak (często odwołanie zwrotne, takie jak delegate/owner), aby umożliwić ARC zwolnienie obu obiektów.
final class Owner2 {
var gadget: Gadget2?
deinit { print("Owner2 deinit") }
}
final class Gadget2 {
weak var owner: Owner2? // weak breaks cycle; becomes nil automatically
deinit { print("Gadget2 deinit") }
}
var o2: Owner2? = Owner2()
var g2: Gadget2? = Gadget2()
o2!.gadget = g2
g2!.owner = o2
o2 = nil // Owner2 deinit
g2 = nil // Gadget2 deinitCykl domknięcia (strong self)
Domknięcia domyślnie przechwytują zmienne za pomocą silnych referencji. Jeśli obiekt posiada również domknięcie, powstaje cykl.
final class TimerClient {
var tick: (() -> Void)?
deinit { print("TimerClient deinit") }
func start() {
// BAD: closure strongly captures self; self keeps tick strongly
tick = {
print("tick from", self) // strong capture of self
}
}
}
var c: TimerClient? = TimerClient()
c!.start()
c = nil // no deinit — closure holds self stronglyPrzerwanie za pomocą list przechwytywania
Należy używać [weak self] (opcjonalnego), aby bezpiecznie zwalniać zasoby; [unowned self] należy stosować wyłącznie wtedy, gdy jest zagwarantowane, że self będzie żyć w chwili wykonania domknięcia.
final class TimerClient2 {
var tick: (() -> Void)?
deinit { print("TimerClient2 deinit") }
func start() {
// Use [weak self] when self can go away before tick runs
tick = { [weak self] in
guard let self = self else { return } // safe unwrap
print("tick from", self)
}
// Alternative when lifetime is guaranteed: [unowned self]
// tick = { [unowned self] in print("tick from", self) }
}
}
var c2: TimerClient2? = TimerClient2()
c2!.start()
c2 = nil // deinit now prints — no cycleLista kontrolna
Lista kontrolna:
- Referencje w obu kierunkach? Należy oznaczyć jedną stronę jako weak (np. delegate).
- Domknięcia przechowywane w typie? Należy przechwytywać [weak self] i bezpiecznie rozpakowywać wartość.
- [unowned self] należy stosować wyłącznie przy zagwarantowanym czasie życia; w przeciwnym razie może dojść do awarii.
weak a unowned w domknięciach
Szybkie sprawdzenie: Która lista przechwytywania jest bezpieczniejsza, gdy obiekt może zostać zwolniony?
Podsumowanie
Podsumowanie: Należy rozpoznawać cykle w obiektach i domknięciach. Należy przerywać je za pomocą odpowiednio dobranych weak lub unowned; w razie wątpliwości preferowane jest weak.
Ucz się Swift dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 122
- Lekcje
- 409
Często zadawane pytania
Czy lekcja „Cykle retencji i ich przerywanie za pomocą weak/unowned” jest bezpłatna?
Tak — pełny tekst „Cykle retencji i ich przerywanie za pomocą weak/unowned” 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 3 lekcji w sumie.
Co nauczysz się w „Cykle retencji i ich przerywanie za pomocą weak/unowned”?
Wykrywajcie cykle retencji między obiektami i closures, a następnie bezpiecznie przerywajcie je za pomocą referencji weak i unowned . Ć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 2 z 3.
Ile czasu zajmuje lekcja „Cykle retencji i ich przerywanie za pomocą weak/unowned”?
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
- Podstawy ARC: strong / weak / unowned
- Cykle retencji i ich przerywanie za pomocą weak/unowned
- Typy wartości ograniczające współdzielenie