Что будет выведено при использовании unowned в замыкании?

Первый вызов печатает 1. После освобождения исходного UIView второй вызов обращается к недействительной unowned-ссылке и завершает выполнение ошибкой.

Короткий ответ

Что ответить на собеседовании

Первый вызов печатает 1. После освобождения исходного UIView второй вызов обращается к недействительной unowned-ссылке и завершает выполнение ошибкой.

Подробный разбор

Ответ с пояснениями

Условие

В данном примере на Swift показано, как замыкание захватывает объект UIView с указанием unowned. Сначала создаётся объект UIView, ему присваивается тег 1, после чего замыкание выводит значение тега. Затем переменной присваивается новый объект UIView с тегом 2, и замыкание вызывается повторно. Нужно понять, какое значение будет напечатано каждый раз.

var container = UIView()
container.tag = 1

let displayTag = { [unowned container] in
    print(container.tag)
}

displayTag()

container = UIView()
container.tag = 2

displayTag()

Ответ

Первый вызов печатает 1. После освобождения исходного UIView второй вызов обращается к недействительной unowned-ссылке и завершает выполнение ошибкой.

Capture list захватывает исходный объект, а не следит за последующими присваиваниями переменной container. unowned не удерживает этот объект. После замены container на новый UIView у старого в показанном коде не остаётся сильной ссылки, поэтому второе чтение tag небезопасно; значение 2 оно не напечатает. Для допуска исчезновения объекта используют [weak container] и optional-проверку, а сильный захват сохранял бы исходный объект и его тег 1.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее