Ответ
Capture list — это синтаксическая конструкция для явного управления захватом переменных в замыкании. [weak self] — это частный и самый распространённый случай capture list.
Ключевое отличие: Capture list позволяет контролировать захват любых переменных из окружающего контекста, а не только self. Она делает зависимости замыкания явными и предотвращает непреднамеренные сильные захваты.
Пример 1: Только weak self (это уже capture list)
closure = { [weak self] in
self?.doWork()
}
Пример 2: Capture list с несколькими переменными
class Processor {
var data: Data
var onComplete: (() -> Void)?
func process(with formatter: Formatter) {
// Захватываем self слабо, а formatter сильно (по умолчанию).
// Это явно показывает, что замыкание зависит от formatter.
someAsyncTask { [weak self, formatter] result in
guard let self = self else { return }
let output = formatter.format(result, using: self.data)
self.finish(with: output)
}
}
}
Пример 3: Захват с переименованием (например, сильная ссылка на self)
networkService.fetchData { [weak self] result in
// Создаём сильную ссылку на self ТОЛЬКО на время выполнения замыкания
guard let strongSelf = self else { return }
strongSelf.handle(result)
strongSelf.cleanup() // safe, strongSelf гарантированно жив
}
Практические правила:
- Всегда используйте capture list (
[weak self],[unowned self]) для явного указания захватаselfво избежание retain cycles. - Захватывайте другие переменные через capture list, если важно явно показать зависимость замыкания или управлять их временем жизни (например,
[weak delegate]). weak selfвнутри тела замыкания без capture list — это ошибка. Capture list определяет, как захватывать, а использованиеself?внутри — это уже работа с захваченной ссылкой.
Итог: Capture list — это обязательный инструмент для безопасной работы с замыканиями, а weak self — его наиболее важный частный случай.