0Pricing
Swift Academy · Lekcja

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 data

Kiedy 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 Sendable

Szybki 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

  1. Problem wyścigu danych
  2. Protokół Sendable
  3. Izolacja aktorów i nonisolated
  4. Migracja do ścisłej współbieżności
← Powrót do Swift Academy