Swift Academy · Урок

Изоляция акторов и nonisolated

Разбирайтесь в границах изоляции.

Урок 3 из 413 шагов

«Изоляция акторов и nonisolated» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Что такое изоляция актора

Изоляция актора означает, что изменяемого состояния актора может касаться только код, выполняющийся в этом акторе.

Среда выполнения сериализует доступ, поэтому две задачи никогда не изменяют состояние одновременно, устраняя гонки данных.

actor Counter {
    private var value = 0
    func increment() { value += 1 }
}

Вызов актора

При обращении к изолированным членам извне актора доступ становится асинхронным. Необходимо использовать await, поскольку вызов может приостановиться, пока актор не освободится.

let counter = Counter()
func useCounter() async {
    await counter.increment()
}

Внутри актора: синхронный доступ

В собственных методах актора Вы уже находитесь в изоляции, поэтому обращаетесь к состоянию синхронно — для самого актора await не требуется.

actor Counter {
    private var value = 0
    func incrementTwice() {
        value += 1 // synchronous: already isolated
        value += 1
    }
}

Члены без изоляции

Помечайте член как nonisolated, если он не обращается к изменяемому состоянию. Такие члены выполняются синхронно откуда угодно, без await.

Это идеально подходит для вычисляемых значений, построенных только на неизменяемых данных.

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    nonisolated var label: String { "User #\(id)" }
}

Почему отсутствие изоляции безопасно

Член nonisolated может только читать неизменяемое (let) или иным образом передаваемое состояние.

Компилятор отклоняет любую попытку обратиться к изменяемому изолированному состоянию из контекста без изоляции.

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    // Error: cannot read mutable sessionCount here
    // nonisolated var bad: Int { sessionCount }
}

Отсутствие изоляции и протоколы

nonisolated необходимо, когда актор соответствует синхронному протоколу. Метод протокола не может быть асинхронным, поэтому он не должен обращаться к изолированному состоянию.

actor Item: CustomStringConvertible {
    let name: String
    init(name: String) { self.name = name }
    nonisolated var description: String { "Item: \(name)" }
}

Главный актор

@MainActor — это глобальный актор, изолирующий код в главном потоке. Обновления пользовательского интерфейса должны выполняться здесь.

Аннотируйте типы, методы или свойства, чтобы закрепить их за главным актором.

@MainActor
final class ViewModel {
    var title = "Hello"
    func refresh() { title = "Updated" }
}

Переход между акторами

При вызове из одного актора в другой среда выполнения переключает исполнителей и приостанавливает выполнение. Именно в этой точке приостановки появляется await.

actor Database { func load() -> Int { 42 } }
@MainActor
func show(_ db: Database) async {
    let v = await db.load() // hop to db actor
    print(v)               // hop back to main
}

Реентерабельность акторов

Акторы являются реентерабельными: когда метод ожидает результат, актор может выполнить другую работу из очереди до возобновления после ожидания.

Состояние, прочитанное до await, после него могло измениться. Повторно проверяйте предположения после точек приостановки.

actor Store {
    var ready = false
    func prepare() async {
        ready = false
        await Task.yield() // other calls may run here
        ready = true
    }
}

Изолированные параметры

Функция может принимать параметр актора с модификатором isolated и выполнять своё тело на этом акторе, не являясь его членом.

func bump(on counter: isolated Counter) {
    // runs isolated to counter; synchronous access
}

Глобальные акторы для подсистем

Можно определить собственный глобальный актор, чтобы изолировать целую подсистему (например, конвейер отрисовки) на одном исполнителе.

@globalActor
actor RenderActor {
    static let shared = RenderActor()
}
@RenderActor func draw() { }

Быстрая проверка: изоляция

Проверьте своё понимание изоляции акторов.

Итоги: изоляция акторов и отсутствие изоляции

Изоляция акторов сериализует доступ к изменяемому состоянию; вызовы между акторами являются асинхронными и требуют await. Члены nonisolated не участвуют в изоляции, но могут читать только неизменяемое или передаваемое состояние, что крайне важно для соответствия синхронным протоколам.

@MainActor закрепляет код за главным потоком, акторы являются реентерабельными (состояние может измениться между вызовами await), а глобальные акторы изолируют целые подсистемы. Освоение этих правил — основа безопасного конкурентного выполнения.

Можно начать бесплатно

Изучай Swift с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
122
Уроки
409

Часто задаваемые вопросы

Урок «Изоляция акторов и nonisolated» бесплатный?

Да — полный текст урока «Изоляция акторов и nonisolated» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Изоляция акторов и nonisolated»?

Разбирайтесь в границах изоляции. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Изоляция акторов и nonisolated»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Проблема гонки данных
  2. Протокол Sendable
  3. Изоляция акторов и nonisolated
  4. Переход на строгую конкурентность
← Назад к Swift Academy