Списки захвата — weak/unowned и захват значений
Используйте списки захвата, чтобы управлять захватом ссылок и значений замыканиями: [weak self], unowned и снимки значений помогают избежать циклов удержания и трудноуловимых ошибок.
«Списки захвата — weak/unowned и захват значений» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 3 уроков всего.
Зачем нужны списки захвата?
Цель: управлять тем, что и как захватывает closure. Используйте [слабая ссылка на self] или ссылку без владения, чтобы избежать циклов удержания, и создавайте снимки значений, когда это необходимо.
Сильный захват = риск цикла
Сохраняющиеся или хранимые closure удерживают захваченные значения. Сильный захват self в этом случае может создать цикл удержания.
class Owner {
var name = "Owner"
var onDone: (() -> Void)?
func start() {
// Strong capture of self can cause a cycle if onDone is stored:
onDone = {
print("Done by", self.name) // self captured strongly
}
}
}
var o: Owner? = Owner()
o?.start()
// If nothing nils onDone or o, both can keep each other alive.Шаблон слабого захвата
Используйте [слабая ссылка на self], чтобы разорвать цикл. self внутри становится необязательным; извлекайте его с помощью проверки или необязательной цепочки вызовов.
class Owner2 {
var name = "Owner2"
var onDone: (() -> Void)?
func start() {
onDone = { [weak self] in
guard let self = self else { return } // safely unwrap optional self
print("Done by", self.name)
}
}
}
let o2 = Owner2()
o2.start()
o2.onDone?()Ссылка без владения — используйте осторожно
Ссылка без владения предполагает, что self переживёт closure и не будет необязательным. Используйте её только будучи уверенными, что в момент вызова значение не может быть отсутствующим.
class Owner3 {
var onDone: (() -> Void)?
func work() {
onDone = { [unowned self] in
// self must be alive when this runs; otherwise crash
print("Owner3 still alive")
}
}
}
let o3 = Owner3()
o3.work()
o3.onDone?()Идея снимка значения
Списки захвата могут сохранять снимки значений, например [n = count]. Без списка константы let внутри всё равно захватываются при создании.
var count = 0
let makeLogger: () -> () -> Void = {
let snapshot = count // captured by value at creation
return {
print("snapshot =", snapshot, "current =", count)
}
}
count = 10
let logger = makeLogger()
count = 20
logger() // snapshot = 10, current = 20Привязка значения в списке захвата
Используйте список захвата, чтобы создать снимок именованного значения, например [initial = total], в момент создания closure.
var total = 5
let closure = { [initial = total] in
print("initial:", initial, " now:", total)
}
total = 9
closure() // initial uses captured value 5Зачем нужна слабая ссылка на self
Быстрая проверка: зачем добавлять [weak self] в хранимый или сохраняющийся closure?
Итоги
Итоги: используйте [слабая ссылка на self], чтобы разорвать циклы — self становится необязательным; применяйте ссылку без владения только при гарантированном времени жизни и сохраняйте снимки значений с помощью привязок в списке захвата.
Часто задаваемые вопросы
Урок «Списки захвата — weak/unowned и захват значений» бесплатный?
Да — полный текст урока «Списки захвата — weak/unowned и захват значений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 3 уроков всего.
Чему я научусь в уроке «Списки захвата — weak/unowned и захват значений»?
Используйте списки захвата, чтобы управлять захватом ссылок и значений замыканиями: [weak self], unowned и снимки значений помогают избежать циклов удержания и трудноуловимых ошибок. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.
Сколько времени занимает урок «Списки захвата — weak/unowned и захват значений»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы замыканий и захвата
- Списки захвата — weak/unowned и захват значений
- Escaping и нез escaping-замыкания, автозамыкания