Первый вызов печатает 1. После освобождения исходного UIView второй вызов обращается к недействительной unowned-ссылке и завершает выполнение ошибкой.
Что будет выведено при использовании 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.