Ответ
Использовать [weak self] не всегда обязательно. Это требуется для предотвращения цикла сильных ссылок (retain cycle), который возникает, когда объект и захваченное им замыкание удерживают друг друга, что приводит к утечке памяти.
Когда [weak self] НЕ нужен?
- Синхронное выполнение: Замыкание выполняется немедленно и не сохраняется.
let squares = numbers.map { $0 * $0 } // Нет цикла, замыкание живет только на время вызова `map`. - Замыкание не захватывает
self:DispatchQueue.main.async { print("Выполнено") // self не используется } - Использование
[unowned self]: В строго контролируемых сценариях, где время жизни объекта гарантированно превышает время жизни замыкания (рискованно).
Когда [weak self] ОБЯЗАТЕЛЕН?
- Асинхронные вызовы с сохранением замыкания: Когда замыкание хранится как свойство или передается в асинхронную операцию (сеть, таймеры, анимации с completion).
class DataLoader { func loadData(completion: @escaping (Result) -> Void) { networkService.fetch { [weak self] result in // Обязательно weak! self?.handle(result) // self стал optional completion(result) } } } -
Захват
selfв замыкании, которое само является свойством этогоself: Классический цикл.class MyClass { var closure: (() -> Void)? func setup() { // ЦИКЛ: self -> closure -> self closure = { self.doSomething() } // УТЕЧКА! // Решение: closure = { [weak self] in self?.doSomething() } } }
Практическое правило
Если замыкание является @escaping и внутри него используется self — в 99% случаев нужен [weak self]. Всегда анализируйте жизненные циклы объектов.