Предскажите вывод, когда захваченную переменную меняют после захвата
Прочитайте фрагмент. Одно замыкание захватывает x в списке захвата [x]; другое — без списка захвата. Затем x меняют до запуска обоих замыканий.
var x = 1
let byValue = { [x] in print(x) }
let byReference = { print(x) }
x = 99
byValue()
byReference()
Что напечатает каждый вызов и почему? Объясните разницу, которую вносит список захвата. Определите вывод.
byValue() печатает 1; byReference() печатает 99. Список захвата [x] копирует x по значению при создании замыкания, поэтому позднее изменение x для него невидимо. Без списка захвата замыкание захватывает переменную по ссылке и читает её текущее значение в момент вызова — 99.
- ✗Думают, что список захвата — лишь стилевая подсказка без эффекта в рантайме
- ✗Считают, что голый захват снимает значение в момент создания
- ✗Полагают, что оба замыкания всегда печатают одно и то же значение
- →Чем
[weak self]отличается от[x]в том, что именно захватывается? - →Почему захват по ссылке читает значение в момент вызова, а не создания?
Вывод: 1, затем 99.
var x = 1
let byValue = { [x] in print(x) } // копирует x = 1 сейчас
let byReference = { print(x) } // читает x при вызове
x = 99
byValue() // 1 — значение зафиксировано в момент создания
byReference() // 99 — читает текущее значение x
Список захвата [x] вычисляет x и сохраняет копию в момент создания замыкания, поэтому последующее x = 99 его не затрагивает. Без списка захвата замыкание держит саму переменную и читает её значение в момент вызова, уже после присваивания, — отсюда 99.