Ответ вслух Middle Типы значений и ссылочные обновлено

Как работает copy-on-write в Swift

Вопрос

Расскажите, как устроен copy-on-write и где он есть в Swift.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Copy-on-write это оптимизация типов значений с большим хранилищем. Структура Array хранит ссылку на буфер в куче.

Что должно прозвучать в ответе

  • Присваивание коллекции не копирует элементы, обе переменные делят буфер

  • Перед мутацией проверяется уникальность ссылки на буфер (`isKnownUniquelyReferenced`)

  • Если буфер общий, он копируется, затем меняется копия

  • Есть у `Array`, `Dictionary`, `Set`, `String`; у своих структур автоматически нет

  • Свою реализацию делают через приватный класс-хранилище

Что могут спросить следом

  • Что будет с производительностью, если мутировать копию в цикле?
  • Почему isKnownUniquelyReferenced не работает с ObjC-объектами?

Разбор

Copy-on-write это оптимизация типов значений с большим хранилищем. Структура Array хранит ссылку на буфер в куче. Когда я пишу var b = a, копируется только эта ссылка, счётчик ссылок буфера становится 2. Перед любой мутацией массив вызывает isKnownUniquelyReferenced: если ссылка единственная, меняет буфер на месте, если нет, сначала копирует буфер, и дальше у каждой переменной свой. Снаружи это выглядит как обычная семантика значения, но без лишних копий. Так работают Array, Dictionary, Set и String. Мои структуры этого сами не умеют: если внутри большой класс-хранилище, я должен сам проверять уникальность в мутирующих методах. Ловушка: если держать лишнюю копию массива, каждая первая мутация будет стоить O(n).

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.