> Что копируется, а что передается по ссылке в Swift (iOS, Swift)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Avito

Стек: iOS, Swift

> Пример ответа

Короткий ответ

В Swift семантика передачи зависит от типа: value types (структуры, перечисления, кортежи, базовые типы) копируются по значению, reference types (классы, замыкания, функции) передаются по ссылке. Копирование структур - фактическое копирование данных, но с оптимизацией copy-on-write для коллекций. Классы передаются как указатели на один и тот же объект в памяти, поэтому изменения через любую ссылку видны всем. Важно: copy-on-write делает копирование структур дешёвым до первого изменения.

Подробное объяснение

Value types в Swift - это структуры, перечисления, кортежи, а также все примитивные типы (Int, String, Array, Dictionary, Set). При присваивании или передаче в функцию создаётся независимая копия значения. Изменение копии не влияет на оригинал. Это гарантирует предсказуемость и потокобезопасность.

Reference types - классы, замыкания, функции. При присваивании копируется только ссылка (указатель) на объект в heap. Все ссылки указывают на один и тот же экземпляр, поэтому мутация через любую ссылку видна через все остальные. Управление памятью - через ARC (Automatic Reference Counting).

Ключевой нюанс - copy-on-write (COW). Стандартные коллекции Swift (Array, Dictionary, Set) - это структуры, но внутри они используют буфер в heap. При копировании структуры буфер не копируется физически, а создаётся новая ссылка на тот же буфер. Реальное копирование происходит только при первой мутации одной из копий. Это позволяет избежать лишних аллокаций.

Важно различать: если класс содержит свойства-структуры, то при копировании ссылки на класс сами структуры не копируются - они остаются в том же объекте. Если структура содержит свойство-класс, то при копировании структуры копируется только ссылка на класс, сам объект класса остаётся общим.

На практике

На практике это влияет на выбор между struct и class. Для моделей данных, DTO, конфигураций, value objects - предпочтительны структуры. Для сущностей с идентичностью, общим состоянием, жизненным циклом - классы.

При передаче структур в функции и методы нет риска случайной мутации оригинала - это упрощает отладку и тестирование. Но если структура большая и часто копируется, это может привести к лишним аллокациям, хотя COW смягчает проблему для коллекций.

Для классов нужно быть осторожным с гонками данных при многопоточности - общее состояние требует синхронизации. Также нужно помнить о циклах сильных ссылок и использовать weak/unowned.

Пример кода

SWIFT
// Value type - структура
struct Point {
var x: Int
var y: Int
}
var p1 = Point(x: 1, y: 2)
var p2 = p1 // копия
p2.x = 10
print(p1.x) // 1 - оригинал не изменился
// Reference type - класс
class Person {
var name: String
init(name: String) { self.name = name }
}
let person1 = Person(name: "Alice")
let person2 = person1 // ссылка на тот же объект
person2.name = "Bob"
print(person1.name) // "Bob" - изменение видно через обе ссылки
// Copy-on-write для Array
var arr1 = [1, 2, 3]
var arr2 = arr1 // буфер общий, копирования нет
arr2.append(4) // здесь происходит реальное копирование
print(arr1.count) // 3
print(arr2.count) // 4

Как отвечать на собеседовании

Начни с чёткого разделения: value types копируются, reference types передаются по ссылке. Затем объясни механизм COW для коллекций - это покажет глубину понимания. Приведи примеры из практики: почему модели делают структурами, а координаторы или сервисы - классами. Упомяни влияние на память и производительность. Если спросят про замыкания - объясни, что они тоже reference types и захватывают переменные по ссылке. Хорошо добавить про ARC и weak ссылки для классов.

Что проверяет интервьюер

Интервьюер проверяет: понимание фундаментального различия между struct и class, знание механизма COW, умение объяснить последствия выбора типа для архитектуры, понимание управления памятью (ARC, ссылочные циклы), способность рассуждать о производительности и потокобезопасности. Для senior важно не просто перечислить факты, а показать системное мышление и практический опыт.

Типичные ошибки

  • Утверждение, что структуры всегда копируются полностью - забывают про COW.
  • Путаница между копированием структуры и копированием ссылки на класс внутри структуры.
  • Игнорирование того, что замыкания - reference types.
  • Непонимание, что при передаче класса в функцию передаётся ссылка, а не копия объекта.
  • Утверждение, что String - класс (это структура с COW).
  • Забывают про weak/unowned при разговоре о классах и замыканиях.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью