Циклы удержания и разрыв с помощью weak/unowned
Находите циклы удержания между объектами и замыканиями, а затем безопасно разрывайте их с помощью ссылок weak и unowned .
«Циклы удержания и разрыв с помощью weak/unowned» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 3 уроков всего.
Что такое цикл удержания?
Цикл удержания возникает, когда объекты или замыкания содержат сильные ссылки друг на друга, поэтому ARC никогда не достигает нулевого счётчика. Разрывайте циклы с помощью слабых ссылок или ссылок без владения.
Цикл объект ↔ объект
Две сильные ссылки в обоих направлениях создают утечку: ни один объект не может достичь нулевого счётчика.
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)Разрыв с помощью слабой ссылки
Сделайте одну сторону слабой (часто это обратная ссылка, например ссылка на делегат или владельца), чтобы ARC мог освободить оба объекта.
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 deinitЦикл замыкания (сильная ссылка на self)
Замыкания по умолчанию захватывают переменные сильными ссылками. Если объект также владеет замыканием, образуется цикл.
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 stronglyРазрыв с помощью списков захвата
Используйте список захвата со слабой ссылкой на self для безопасной очистки; используйте список захвата со ссылкой без владения на self только если гарантируется, что self будет существовать во время выполнения замыкания.
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 cycleКонтрольный список
Контрольный список:
- Есть ссылки в обоих направлениях? Сделайте одну сторону слабой (например, ссылку на делегат).
- Замыкания хранятся в типе? Захватывайте self слабой ссылкой и безопасно разворачивайте значение.
- Используйте self со ссылкой без владения только при гарантированном времени жизни; иначе возможен сбой.
Слабая ссылка и ссылка без владения в замыканиях
Быстрая проверка: какой список захвата безопаснее, если объект может быть освобождён?
Повторение
Повторение: выявляйте циклы в объектах и замыканиях. Разрывайте их подходящим образом с помощью слабых ссылок или ссылок без владения; если сомневаетесь, предпочитайте слабую ссылку.
Изучай Swift с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 122
- Уроки
- 409
Часто задаваемые вопросы
Урок «Циклы удержания и разрыв с помощью weak/unowned» бесплатный?
Да — полный текст урока «Циклы удержания и разрыв с помощью weak/unowned» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 3 уроков всего.
Чему я научусь в уроке «Циклы удержания и разрыв с помощью weak/unowned»?
Находите циклы удержания между объектами и замыканиями, а затем безопасно разрывайте их с помощью ссылок weak и unowned . Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.
Сколько времени занимает урок «Циклы удержания и разрыв с помощью weak/unowned»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы ARC: strong / weak / unowned
- Циклы удержания и разрыв с помощью weak/unowned
- Типы-значения для уменьшения совместного использования