В чем отличие структуры от класса в Swift
Что проверяют
Понимаете ли вы разницу между значимыми и ссылочными типами и её последствия: копирование, идентичность, многопоточность. Один из самых частых вопросов по Swift.
Как отвечать
Структура это значимый тип: при присваивании и передаче создаётся копия, каждый владелец работает со своими данными. Класс это ссылочный тип: копируется ссылка, а объект остаётся один на всех.
Что из этого следует:
- наследование есть только у классов, структуры расширяются протоколами и композицией;
- идентичность: у объектов класса есть
===, у структур только сравнение по значению черезEquatable; - изменяемость: метод структуры, меняющий её поля, помечается
mutating, а структура в константе неизменяема целиком. У класса можно менять свойства и через константную ссылку; - память и жизненный цикл: классы живут в куче и управляются подсчётом ссылок, поэтому у них есть
deinitи риск циклов сильных ссылок. Структуры чаще размещаются на стеке и освобождаются автоматически; - многопоточность: копия структуры не разделяется между потоками, поэтому гонок с ней меньше. Это и есть главный аргумент в пользу значимых типов.
Опасение, что копирование дорого, снимается копированием при записи: Array, String и Dictionary копируют содержимое только при попытке изменить его, пока владелец не один.
Ориентир Apple: по умолчанию структура, класс берут, когда нужна идентичность объекта, наследование, взаимодействие с Objective-C или общее изменяемое состояние, которое обязано быть одним на всех.
Где спотыкаются
Ожидают, что изменение копии отразится на оригинале, и ловят неожиданное поведение при передаче структуры в функцию.
Забывают про [weak self] в замыканиях внутри классов и получают утечки.
Считают структуры всегда быстрее. Очень большая структура копируется дорого, и это стоит измерять, а не предполагать.