Protokół Sendable
Oznaczanie typów jako bezpiecznych do przekraczania granic współbieżności.
Protokół Sendable to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Znaczenie Sendable
Sendable to protokół znacznikowy. Typ zgodny z tym protokołem gwarantuje, że można go bezpiecznie współdzielić między domenami współbieżności bez wprowadzania wyścigów danych.
Nie zawiera żadnych metod — jest sprawdzaną przez kompilator gwarancją bezpieczeństwa względem wątków.
protocol Sendable {}Typy wartości często są Sendable
Struktury i typy wyliczeniowe, których wszystkie przechowywane właściwości są zgodne z Sendable, mogą automatycznie uzyskać tę zgodność.
Ponieważ wartości są kopiowane podczas przekazywania, każde zadanie otrzymuje własną, niezależną kopię.
struct User: Sendable {
let id: Int
let name: String
}Niejawna zgodność
Wiele typów wartości uzyskuje zgodność z Sendable niejawnie: niepubliczne zamrożone struktury i typy wyliczeniowe z elementami zgodnymi z Sendable, krotki typów zgodnych z Sendable oraz metatypy.
W przypadku wewnętrznych typów wartości często w ogóle nie trzeba zapisywać : Sendable.
enum Direction { case north, south, east, west }
// Implicitly Sendable: no associated non-Sendable dataKiedy struktura NIE jest Sendable
Jeśli struktura przechowuje właściwość stored, która nie jest typu Sendable, sama nie jest typu Sendable.
W tym przypadku referencja do klasy umożliwia dostęp do współdzielonego, modyfikowalnego stanu, dlatego kompilator odmawia automatycznego spełnienia protokołu.
final class Box { var value = 0 }
struct Wrapper { // not Sendable
let box: Box // class with mutable state
}Klasy i Sendable
Klasy są typami referencyjnymi, więc ich kopie współdzielą tę samą instancję. Klasa jest typu Sendable tylko wtedy, gdy jest oznaczona jako final, a wszystkie jej przechowywane właściwości są niemutowalne i typu Sendable.
final class ImmutablePoint: Sendable {
let x: Double
let y: Double
init(x: Double, y: Double) { self.x = x; self.y = y }
}@unchecked Sendable
Czasami wiadomo, że klasa jest bezpieczna wątkowo, ponieważ chroni stan za pomocą blokady, ale kompilator nie potrafi tego udowodnić. Użyj @unchecked Sendable, aby ręcznie zadeklarować bezpieczeństwo.
To wyjście awaryjne: odpowiedzialność za poprawność spoczywa na Państwu.
import Foundation
final class Cache: @unchecked Sendable {
private let lock = NSLock()
private var storage: [String: Int] = [:]
func set(_ k: String, _ v: Int) {
lock.lock(); defer { lock.unlock() }
storage[k] = v
}
}Domknięcia @Sendable
Domknięcia również można oznaczać jako @Sendable. Takie domknięcie można przekazywać między granicami współbieżności, dlatego kompilator sprawdza, czy przechwytuje ono wyłącznie wartości typu Sendable.
func run(_ work: @Sendable () -> Void) {
work()
}
let name = "Ada" // immutable, Sendable
run { print(name) }Przechwytywanie zmiennego stanu jest odrzucane
Domknięcie @Sendable nie może przechwytywać zmiennej, ponieważ dwa zadania mogłyby modyfikować ją jednocześnie.
Kompilator zgłasza błąd dotyczący przechwycenia poniżej.
var counter = 0
// Error: @Sendable closure captures mutable var
// run { counter += 1 }Sendable w asynchronicznych API
Punkty wejścia do kodu współbieżnego wymagają typu Sendable. Domknięcia Task są typu @Sendable, a wartości przekazywane do innych aktorów muszą być typu Sendable.
W ten sposób system typów uniemożliwia przedostawanie się danych niebezpiecznych w środowisku wielowątkowym między zadaniami.
func process(_ user: User) async {
Task {
// user is Sendable, safe to capture
print(user.name)
}
}Ograniczenia Sendable w typach generycznych
W typach generycznych można wymagać zgodności z Sendable. Funkcja, która uruchamia zadania z użyciem swojego argumentu, powinna ograniczać ten argument do typu Sendable.
func dispatch<T: Sendable>(_ value: T) {
Task { print(value) }
}Sendable a aktor
Sendable odpowiada na pytanie „czy tę wartość można bezpiecznie przekazać?”, natomiast actor odpowiada na pytanie „jak chronić zmienny stan?”.
Te mechanizmy współdziałają: aktory są niejawnie typu Sendable, ponieważ dostęp do ich stanu jest szeregowany.
actor Logger { } // actors are implicitly SendableSzybki sprawdzian: Sendable
Sprawdź swoją wiedzę na temat zgodności z Sendable.
Podsumowanie: protokół Sendable
Sendable oznacza typy, które można bezpiecznie przekraczać przez granice współbieżności. Niemutowalne typy wartości automatycznie spełniają ten protokół; niemutowalne klasy oznaczone jako final mogą go spełniać; klasy bezpieczne wątkowo używają @unchecked Sendable.
Domknięcia @Sendable mogą przechwytywać wyłącznie wartości typu Sendable, a asynchroniczne API wymaga Sendable, aby zapobiegać niebezpiecznemu współdzieleniu. W połączeniu z aktorami Sendable stanowi fundament bezpieczeństwa przed wyścigami danych w Swift na poziomie systemu typów.
Często zadawane pytania
Czy lekcja „Protokół Sendable” jest bezpłatna?
Tak — pełny tekst „Protokół Sendable” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Protokół Sendable”?
Oznaczanie typów jako bezpiecznych do przekraczania granic współbieżności. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Protokół Sendable”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Problem wyścigu danych
- Protokół Sendable
- Izolacja aktorów i nonisolated
- Migracja do ścisłej współbieżności