Где в памяти хранятся value и reference типы в Swift?
Что проверяют
Не повторите ли вы школьное «структуры на стеке, классы в куче». Правильный ответ сложнее, и именно это здесь и смотрят.
Как отвечать
Ссылочные типы (классы, замыкания, акторы) всегда размещаются в куче, а переменная хранит ссылку. Жизненным циклом управляет подсчёт ссылок ARC.
Значимые типы (структуры, перечисления, кортежи) хранятся там, где живёт их владелец. Локальная переменная функции обычно на стеке, но это не правило, а частый случай. В куче значимый тип оказывается, когда:
- он является свойством объекта класса, потому что весь объект лежит в куче;
- захвачен убегающим замыканием, которое переживает вызов функции;
- упакован в протокольный тип или
Anyи не помещается во встроенный буфер; - лежит в косвенном перечислении или рекурсивной структуре;
- хранится в коллекции:
Array,DictionaryиSetсами структуры, но их буфер всегда в куче.
Отдельно стоит сказать про копирование при записи: копия массива или строки дешёвая, реальное копирование буфера происходит при первой мутации, если ссылок на него больше одной. Проверить единоличность владения в своём типе можно через isKnownUniquelyReferenced.
И про оптимизатор: значение, не покидающее функцию, компилятор может разместить на стеке, даже если формально это объект. Смотреть на это стоит инструментами, а не предположениями.
Где спотыкаются
Формулируют как жёсткое правило и не могут объяснить, где лежит структура, объявленная полем класса.
Считают, что массив структур целиком на стеке.
Забывают про цену ARC: она относится к ссылочным типам и внутренним буферам коллекций, а не к самим структурам.