iOS
Сложный
Что такое Actor в Swift? Какую проблему он решает?
Actor в Swift
Проблема: Data Race
// НЕБЕЗОПАСНО: data race
class Counter {
var value = 0
func increment() {
value += 1 // Не атомарно!
}
}
let counter = Counter()
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
counter.increment() // Data race!
}
print(counter.value) // Непредсказуемо
Решение: Actor
actor Counter {
var value = 0
func increment() {
value += 1 // Безопасно
}
func getValue() -> Int {
return value
}
}
let counter = Counter()
// Доступ только через await
await counter.increment()
let value = await counter.getValue()
Как работает:
- Изоляция — только один вызов одновременно
- Сериализация — вызовы выполняются последовательно
- await — обязателен для доступа извне
Actor Isolation:
actor BankAccount {
let accountNumber: String // Неизолированное (immutable)
var balance: Double // Изолированное
init(accountNumber: String) {
self.accountNumber = accountNumber
self.balance = 0
}
func deposit(_ amount: Double) {
balance += amount
}
// nonisolated — доступ без await
nonisolated func getAccountNumber() -> String {
return accountNumber // OK — immutable
}
}
MainActor:
@MainActor
class ViewModel: ObservableObject {
@Published var data: [String] = []
func loadData() async {
let result = await fetchFromNetwork()
data = result // Безопасно на main thread
}
}
// Или для метода
@MainActor
func updateUI() {
label.text = "Updated"
}
Sendable:
// Типы, безопасные для передачи между actors
struct Message: Sendable {
let text: String
}
actor MessageQueue {
func send(_ message: Message) {
// OK — Message is Sendable
}
}
Actor vs Class:
| Аспект | Actor | Class |
|---|---|---|
| Thread-safe | Да | Нет |
| Наследование | Нет | Да |
| Доступ к свойствам | await | Прямой |
| Reference type | Да | Да |
Ограничения:
- Actor не может наследовать от других actors
- Может реализовывать протоколы
- GlobalActor для глобальной изоляции
Похожие вопросы
Готовитесь к собеседованию?
ENIGMA AI — невидимый ИИ-помощник для технических интервью
Попробовать бесплатно