Ответ
Actor решает проблему гонок данных (data races) при работе с изменяемым состоянием в параллельном коде.
Ключевые решаемые проблемы:
- Data Races: Гарантирует, что доступ к изолированному (isolated) состоянию актора происходит последовательно. В один момент времени только одна задача может исполнять код, работающий с его свойствами.
- Упрощение синхронизации: Избавляет разработчика от необходимости вручную использовать примитивы синхронизации (
DispatchQueue,NSLock, семафоры), которые подвержены ошибкам (deadlocks, priority inversion). - Безопасность на уровне компилятора: Компилятор Swift статически проверяет, что код вне актора не обращается к его изолированным свойствам напрямую, вынуждая использовать
awaitдля взаимодействия.
Принцип работы: Actor изолирует свои изменяемые свойства. Все его методы и свойства, помеченные как nonisolated, считаются безопасными для параллельного доступа. Для вызова изолированного метода извне требуется await, что указывает на потенциальную приостановку текущей задачи до возможности безопасного доступа.
Пример:
actor BankAccount {
private(set) var balance: Double = 0.0 // Изолированное состояние
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) -> Bool {
guard balance >= amount else { return false }
balance -= amount
return true
}
}
// Использование
Task {
let account = BankAccount()
await account.deposit(amount: 100) // Доступ сериализован
let success = await account.withdraw(amount: 50)
print("Withdrawal successful:", success)
}
Важно: Actor защищает от гонок данных, но не от всех проблем параллелизма (например, race conditions на логическом уровне или голодание).