Циклы сильных ссылок: Замыкания захватывают переменные из окружающего контекста. Если замыкание и захваченный объект имеют сильные ссылки друг на друга, возникает цикл, предотвращающий освобождение памяти. Решается с помощью списков захвата (capture lists).
Списки захвата (capture lists): Определяют правила захвата переменных.
weak: Ссылается на объект слабо. Объект может быть nil.unowned: Ссылается на объект без владения, предполагая, что объект не станет nil до выполнения замыкания. Опасен, если предположение неверно.unowned(unsafe): Аналогично unowned, но без проверок времени выполнения. Использовать с крайней осторожностью.swift
Изменяемость захваченных переменных: По умолчанию захваченные классы и их свойства изменяемы, а структуры и перечисления - нет. Чтобы изменить захваченную структуру/перечисление внутри замыкания, необходимо помечать замыкание как @escaping и использовать inout или создавать копию.
@escaping атрибут: Указывает, что замыкание будет выполнено позже, не сразу после вызова функции, которая его принимает. Это означает, что замыкание "убегает" из области видимости функции. Требуется для асинхронных операций, колбэков и т.д. Захват self в @escaping замыканиях требует явного указания ([weak self] или [unowned self]) для предотвращения циклов.
@autoclosure атрибут: Автоматически оборачивает выражение в замыкание без параметров. Используется для ленивого вычисления.
@noescape (поведение по умолчанию до Swift 3): Указывает, что замыкание не "убегает" из функции. Сейчас поведение по умолчанию.
@Sendable протокол: Позволяет использовать замыкания в контексте конкурентности, гарантируя их безопасное использование между потоками. Замыкание должно захватывать только Sendable типы.
Таблица сравнения weak и unowned:
| Признак | weak | unowned |
|---|---|---|
| Тип ссылки | Слабая | Безусловная (Unowned) |
| Возможность nil | Да (опционал) | Нет (не опционал, разыменование nil вызывает ошибку) |
| Жизненный цикл | Захваченный объект может существовать дольше замыкания | Захваченный объект должен существовать дольше или столько же, сколько замыкание |
| Безопасность | Более безопасный при неопределенном времени жизни объекта | Опасен при неопределенном времени жизни объекта |