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 — локальная установка не требуется.
Все уроки этого курса
- TaskGroup для параллельного выполнения
- Акторы и изоляция данных, nonisolated
- Sendable и проверка потокобезопасности