Ответ
Замыкания в Swift являются ссылочными типами (reference types). Они размещаются в куче (heap), и при присваивании замыкания новой переменной или передаче в функцию копируется ссылка на один и тот же экземпляр замыкания, а не его содержимое.
Почему это важно:
- Изменения состояния переменных, захваченных замыканием (
captured variables), видны всем владельцам ссылки на это замыкание. - Это поведение отличается от структур (value types), которые копируются.
Пример, демонстрирующий reference semantics:
var counter = 0
let incrementer = { counter += 1 } // Замыкание захватывает `counter` по сильной ссылке
let anotherReference = incrementer // Копируется ссылка, а не новое замыкание
incrementer() // counter = 1
anotherReference() // counter = 2
print(counter) // Выведет: 2
Управление захватом: Чтобы избежать непреднамеренного совместного использования состояния, используйте списки захвата (capture lists). Например, [counter] захватит копию значения на момент создания замыкания.
Ответ 18+ 🔞
Слушай, а вот замыкания в Swift — это же, блядь, чистой воды ссылочные типы, как классы! Не как структуры, которые тупо копируются, а вот эта вот, понимаешь, ебаная сущность, которая живёт в куче. Как ты её ни присваивай, ни передавай — ты везде таскаешь одну и ту же пиздатую ссылку на один и тот же кусок памяти. Один экземпляр на всех, как последняя пачка сигарет в роте.
И в чём же, блядь, подвох?
А подвох в том, что если твоё замыкание что-то там внутри себя меняет — какую-нибудь захваченную переменную — то все, у кого есть ссылка на это замыкание, увидят эти изменения. Это не как с Int или String, где у каждого своя копия и похуй. Тут всё сообща, как в коммуналке.
Смотри, какой пиздатый пример:
var counter = 0
let incrementer = { counter += 1 } // Замыкание схватило `counter` и не отпускает, жадная сука
let anotherReference = incrementer // Скопировалась не суть, а ссылка! Теперь они как сиамские близнецы.
incrementer() // counter = 1
anotherReference() // counter = 2
print(counter) // Выведет: 2. Охуеть, да? Обе ссылки долбили один и тот же счётчик!
Как не облажаться?
А вот для этого, друг мой, есть списки захвата. Хочешь заморозить значение на момент создания, а не тащить живую ссылку? Пожалуйста! Захвати [counter] — и будет тебе отдельная, ни от кого не зависящая копия. Как будто сфоткал и носил с собой, а оригинал пусть себе живёт своей жизнью.