Swift Academy · Урок

Циклы удержания и разрыв с помощью weak/unowned

Находите циклы удержания между объектами и замыканиями, а затем безопасно разрывайте их с помощью ссылок weak и unowned .

Урок 2 из 38 шагов

«Циклы удержания и разрыв с помощью 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 — локальная установка не требуется.

Все уроки этого курса

  1. Основы ARC: strong / weak / unowned
  2. Циклы удержания и разрыв с помощью weak/unowned
  3. Типы-значения для уменьшения совместного использования
← Назад к Swift Academy