0Pricing
Swift Academy · Урок

Sendable и проверка потокобезопасности

Помечайте данные как Sendable , пишите замыкания @Sendable и выбирайте между типами-значениями, акторами и @unchecked Sendable для потокобезопасного совместного использования.

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

Что такое Sendable?

Sendable — это способ Swift гарантировать безопасность передачи данных между параллельными задачами и акторами.

  • Большинство структур и перечислений автоматически являются Sendable.
  • Классы по умолчанию не являются Sendable.
  • Используйте акторы или @unchecked Sendable — редко и только при ручном обеспечении безопасности.

Типы-значения — это просто

Структуры с членами Sendable являются Sendable; безопасно передавать их между задачами.

// Value types with value-only stored properties are Sendable.
// They are safe to transfer across tasks.
struct Point: Sendable { let x: Int; let y: Int }

func shift(_ p: Point) -> Point { Point(x: p.x + 1, y: p.y + 1) }

// Use in parallel tasks
Task {
    let p = Point(x: 1, y: 2)
    async let a = shift(p)
    async let b = shift(p)
    let (p1, p2) = await (a, b)
    print(p1, p2) // Point(x: 2, y: 3) Point(x: 2, y: 3)
}

Классы: используйте акторы

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

// Reference types (class) are not Sendable by default.
// Prefer actors to guard mutable state.
actor SafeCounter {
    private var value = 0
    func inc() { value += 1 }
    func read() -> Int { value }
}

let counter = SafeCounter()
Task {
    async let t1 = counter.inc()
    async let t2 = counter.inc()
    _ = await (t1, t2)
    print(await counter.read()) // 2
}

// (Alternative) A plain class would need locks + @unchecked Sendable; see later.

Замыкания @Sendable

Помечайте замыкания как @Sendable, если они могут выполняться в других исполнителях. Не захватывайте изменяемое состояние, не являющееся Sendable.

// Some APIs require closures to be @Sendable so captured values are safe.
func doTwice(_ f: @Sendable () -> Int) -> Int { f() + f() }

let base = 10
// Capturing an immutable value (let) is fine for @Sendable closures.
let result = doTwice { base + 1 }
print(result) // 22

// Detached tasks also use @Sendable under the hood:
let t = Task.detached { () -> Int in
    // Do not capture non-Sendable mutable state here.
    return 5 * 5
}
Task { print(await t.value) }

@unchecked Sendable (расширенный уровень)

@unchecked Sendable отключает проверки компилятора. Используйте это только при строгой внутренней синхронизации с помощью блокировок или очередей и лишь в крайнем случае.

import Foundation

// Only when you KNOW it is safe: wrap with a lock and mark @unchecked Sendable.
final class Box<T>: @unchecked Sendable {
    private var value: T
    private let lock = NSLock()

    init(_ value: T) { self.value = value }

    func read() -> T {
        lock.lock(); defer { lock.unlock() }
        return value
    }

    func write(_ newValue: T) {
        lock.lock(); value = newValue; lock.unlock()
    }
}

let shared = Box<Int>(0)
let a = Task.detached { shared.write(1) }
let b = Task.detached { shared.write(2) }
Task {
    _ = await (a.value, b.value)
    print(shared.read()) // 1 or 2 (last writer wins, but no data race)
}

Рекомендации

Рекомендации:

  • Предпочитайте типы-значения, удобные для Sendable.
  • Используйте акторы для общего изменяемого состояния.
  • Пишите замыкания @Sendable; избегайте захвата изменяемых значений, не являющихся Sendable.
  • Используйте @unchecked Sendable только при строгой синхронизации.

Значение Sendable

Быстрая проверка: что гарантирует Sendable?

Итоги

Итоги: используйте Sendable для моделирования безопасности при работе между задачами, отдавайте предпочтение акторам или типам-значениям, пишите замыкания @Sendable, а @unchecked Sendable применяйте только для внутреннего кода с надёжной синхронизацией.

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

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

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

Чему я научусь в уроке «Sendable и проверка потокобезопасности»?

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

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

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

Сколько времени занимает урок «Sendable и проверка потокобезопасности»?

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

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

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

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

  1. TaskGroup для параллельного выполнения
  2. Акторы и изоляция данных, nonisolated
  3. Sendable и проверка потокобезопасности
← Назад к Swift Academy