Ответ
Capture list (список захвата) — это синтаксическая конструкция в Swift, которая явно определяет, как замыкание захватывает переменные и константы из окружающего контекста. Её основная цель — управление памятью и предотвращение сильных циклов ссылок (retain cycles).
Базовый синтаксис: { [capture_specification] in ... }
Пример проблемы и решения:
class ViewController {
var counter = 0
var closure: (() -> Void)?
func setupProblem() {
// ПРОБЛЕМА: Сильный цикл! Замыкание сильно захватывает `self`,
// а `self` сильно хранит замыкание в свойстве `closure`.
closure = {
self.counter += 1 // Сильный захват self
}
}
func setupSolution() {
// РЕШЕНИЕ: Используем capture list для слабого захвата.
closure = { [weak self] in
self?.counter += 1 // self теперь опциональный
}
}
}
Основные типы захвата в списке:
[weak object]: Захват слабой (weak) ссылки. Объект становится опциональным (T?) внутри замыкания. Используется для разрыва retain cycles.[unowned object]: Захват безусловной (unowned) ссылки. Предполагает, что объект не будет освобожден. Опасен, если предположение неверно.[variable = value]: Захват по значению (value capture). Фиксирует значение переменной на момент создания замыкания.var value = 10 let closure = { [capturedValue = value] in print(capturedValue) // Всегда напечатает 10, даже если внешняя `value` изменится } value = 20 closure() // Вывод: 10
Правило: Всегда используйте capture list ([weak self] или [unowned self]), когда замыкание, хранимое в свойстве класса, захватывает self.