Ответ
Нет, [weak self] требуется не для всех замыканий. Его необходимость определяется риском создания цикла сильных ссылок (retain cycle).
Используй [weak self] (или [unowned self]) когда:
- Объект (
self) хранит сильную ссылку на это замыкание (например, в своем свойстве). - Замыкание выполняется асинхронно или его вызов отложен во времени.
- Жизненный цикл замыкания может превысить жизненный цикл
self.
Пример цикла сильных ссылок:
class ViewController {
var onDataLoaded: (() -> Void)? // Сильная ссылка на замыкание
func setup() {
onDataLoaded = {
self.updateUI() // Замыкание сильно захватывает `self`
}
// `self` -> `onDataLoaded` -> `self` (ЦИКЛ!)
}
}
Исправление с [weak self]:
func setup() {
onDataLoaded = { [weak self] in
self?.updateUI() // `self` теперь опциональная слабая ссылка
}
}
Когда `[weak self] можно опустить:
- Замыкание с немедленным выполнением: Например, в методах высшего порядка
map,filter,forEach, которые выполняются синхронно.let squares = numbers.map { $0 * $0 } // Нет риска цикла - Замыкание не сохраняется: Когда замыкание передается как аргумент и не сохраняется объектом (например, completion-блок в
UIView.animate). - Гарантированный жизненный цикл: Когда время жизни
selfгарантированно больше времени жизни замыкания (редкий случай, часто[unowned self]подходит лучше, но требует осторожности).
Правило: Если есть сомнения — используй [weak self]. Это безопаснее, чем создание цикла или риск краша с unowned.