Почему не рекомендуется использовать классы для моделей в iOS
Что проверяют
Понимаете ли вы разницу значимых и ссылочных типов в Swift и умеете ли объяснить её последствиями, а не заученным «структуры быстрее». Заодно проверяют, знаете ли, когда класс всё же нужен.
Как отвечать
Главный аргумент семантический. Класс это общее изменяемое состояние: два места в приложении держат один экземпляр, одно меняет поле, второе узнаёт об этом неявно и не тогда, когда готово. Структура копируется при присваивании, а внутренние буферы вроде Array и String копируются лениво, поэтому модель ведёт себя предсказуемо и её просто сравнивать в тестах.
Из этого растёт остальное:
- для структуры компилятор синтезирует
Equatable,HashableиCodable, у классаCodableпридётся писать руками, а==по умолчанию нет вовсе, есть только тождество ссылок через===; - SwiftUI решает, перерисовывать ли представление, сравнивая значения. Ссылочная модель этот механизм выключает, и приходится тянуть
ObservableObject, то есть другой инструмент для другой задачи; - ссылки дают циклы и требуют
weakиunowned, у структур такой темы нет; - структуру безопасно передать между задачами, класс приходится защищать актором или очередью, и компилятор потребует
Sendable.
Обязательно назвать обратную сторону: класс уместен там, где нужна именно идентичность или общее состояние по замыслу. Это сетевой клиент, кэш, координатор навигации, объекты Core Data, взаимодействие с Objective-C и KVO.
Где спотыкаются
Повторяют, что структуры лежат в стеке, а классы в куче. Это упрощение: структура внутри класса или захваченная замыканием живёт в куче, а массив внутри структуры всегда хранит буфер в куче. Аргумент про память слабее семантического.
Считают, что struct означает неизменяемость. Изменяемость задаёт var или let у самой переменной, а не выбор типа. Структура с полями var меняется свободно, просто чужая копия об этом не узнает.
Доводят правило до крайности и делают структурами всё подряд, включая то, чему нужна идентичность. Копия менеджера или кэша означает два независимых состояния и баги, которые потом не воспроизводятся.