Class, Struct и Actor в Swift: Полное руководство с примерами

Class, Struct и Actor в Swift: Полное руководство с примерами

Swift предлагает три основных типа данных для работы: struct, class и actor. Они кажутся похожими, но различия между ними влияют на производительность, потокобезопасность и управление памятью. В этой статье мы разберем их особенности, плюсы и минусы, а также разберем, в каких случаях какой тип лучше использовать.

1. Struct – Значимый тип (Value Type)

Class, Struct и Actor в Swift: Полное руководство с примерами

struct (структуры) являются значимыми типами, то есть они передаются по значению. При передаче структуры в другую переменную или функцию создается копия данных, а не передается ссылка.

пример:

struct User { var name: String } var user1 = User(name: "Игорь") var user2 = user1 // Копирование структуры user2.name = "Алексей" print(user1.name) // "Игорь" print(user2.name) // "Алексей"

В этом коде user1 и user2 – это разные объекты, изменение user2.name не влияет на user1.name.

Где используются структуры?

Многие стандартные типы в Swift — это структуры:

✅ Int, Double, String, Array, Dictionary

✅ CGRect, CGSize, CGPoint (работа с графикой)

✅ Date, URL, IndexPath

Преимущества struct

✅ Безопасность потоков – каждый объект имеет свою копию, поэтому нет гонок данных.

✅ Более высокая производительность – структуры хранятся в стеке (если не содержат ссылочные типы).

✅ Простота использования – не нужно следить за управлением памятью через ARC (Automatic Reference Counting).

Когда использовать struct?

🔹 Когда объект можно легко копировать (например, CGPoint, User).

🔹 Когда важна безопасность многопоточности.

🔹 Когда объект не должен изменяться в нескольких местах одновременно.

2. Class – Ссылочный тип (Reference Type)

Class, Struct и Actor в Swift: Полное руководство с примерами

class (классы) передаются по ссылке, то есть несколько переменных могут ссылаться на один и тот же объект.

Пример:

class User { var name: String init(name: String) { self.name = name } } var user1 = User(name: "Игорь") var user2 = user1 // Передача ссылки user2.name = "Алексей" print(user1.name) // "Алексей" print(user2.name) // "Алексей"

Здесь user1 и user2 указывают на один и тот же объект, поэтому изменение в одном месте изменяет объект во всех местах.

Преимущества class

✅ Позволяет изменять состояние – можно изменять объект без создания новых копий.

✅ Поддерживает наследование – в отличие от struct, классы могут наследоваться.

✅ Поддержка ARC (Automatic Reference Counting) – память управляется автоматически.

Недостатки class

❌ Не потокобезопасны – если один поток изменяет объект, другой может получить неконсистентные данные.

❌ Проблемы с управлением памятью – если объекты ссылаются друг на друга, могут возникнуть утечки памяти (retain cycle).

Когда использовать class?

🔹 Когда важна идентичность объекта (например, если два пользователя могут иметь одно имя, но это разные объекты).

🔹 Когда нужен общий доступ к данным (например, для моделей данных, менеджеров ресурсов).

🔹 Когда объект нецелесообразно копировать (например, сетевые запросы, база данных).

3. Actor – Безопасный ссылочный тип для многопоточности

Class, Struct и Actor в Swift: Полное руководство с примерами

Swift 5.5 представил actor – это потокобезопасная версия класса, которая защищает свои свойства и методы от одновременного доступа из разных потоков.

Пример:

actor BankAccount { var balance: Int = 0 func deposit(amount: Int) { balance += amount } } let account = BankAccount() Task { await account.deposit(amount: 100) print(await account.balance) }

Ключевое отличие от классов – actor автоматически гарантирует безопасный доступ к своим данным.

Как работают actor?

🔹 Каждый actor имеет свой потокобезопасный контекст.

🔹 Доступ к данным возможен только через await.

🔹 actor используют синхронизацию потоков, что делает их безопасными.

Преимущества actor

✅ Гарантирует потокобезопасность – нет необходимости вручную использовать DispatchQueue или NSLock.

✅ Идеален для работы с многопоточными данными – например, для сетевых менеджеров, кеширования.

Недостатки actor

❌ Медленнее, чем классы – из-за необходимости синхронизации.

❌ Не поддерживает наследование – в отличие от классов.

Когда использовать actor?

🔹 Когда объект работает в многопоточной среде.

🔹 Когда важна безопасность данных без сложных блокировок.

🔹 Когда класс использовал @MainActor или @Sendable, но нужна более гибкая поддержка потоков.

Сравнительная таблица: struct, class и actor

Class, Struct и Actor в Swift: Полное руководство с примерами

Вывод: что использовать в вашем проекте?

  • Используйте struct, если объект можно легко копировать, он не требует управления ссылками и важна производительность.
  • Используйте class, если объект должен сохранять свое состояние и важна его идентичность.
  • Используйте actor, если ваш объект работает в многопоточной среде и требует потокобезопасности.

🔥 Совет: Если не уверены, с чего начать, используйте struct. Если потребуется управление состоянием или наследование — меняйте на class или actor.

Class, Struct и Actor в Swift: Полное руководство с примерами
Начать дискуссию