Sendable — wat is het, protocol voor draadveiligheid

Auteur: IT Sectr Gepubliceerd: 2026-06-18 Leestijd: 10 min

Sendable — is een Swift-protocol dat typen markeert die veilig zijn voor overdracht tussen threads. Bij het werken met concurrentie (actor, async/await, Task) vereist de Swift-compiler dat alle gegevens die tussen geïsoleerde contexten worden verzonden, voldoen aan Sendable. Dit voorkomt het per ongeluk verzenden van onveilige typen die tot dataraces kunnen leiden. Het protocol fungeert als een contract: een type dat aan Sendable voldoet, garandeert de afwezigheid van interne niet-gesynchroniseerde toestand. Volgens WWDC 2021 is het Sendable-protocol een verplicht element bij het ontwerpen van veilige multithread-architectuur.

Belangrijkste

  • Sendable — protocol dat de afwezigheid van dataraces bij overdracht tussen threads garandeert
  • Waardetypen (struct, enum) voldoen automatisch aan Sendable als al hun eigenschappen Sendable zijn
  • @unchecked Sendable — omzeilingsmechanisme voor klassen waarvan de ontwikkelaar de veiligheid op zich neemt
  • Sendable closures worden gemarkeerd met het @Sendable-attribuut dat het vastleggen van variabelen controleert
  • Compiler geeft een fout als een niet-Sendable type tussen geïsoleerde contexten wordt verzonden

Wat is het Sendable-protocol in Swift?

Sendable — is een protocol uit de standaard Swift-bibliotheek (SE-0302) dat typen markeert die veilig zijn voor overdracht tussen isolatiedomeinen. Onder isolatiedomein wordt een actor, een Task-taak of een @MainActor-context verstaan. Sendable bevat geen vereisten — het fungeert als een veiligheidsmarkering.

Waarom is Sendable nodig

Vóór Swift 5.5 konden ontwikkelaars elk object tussen threads verzenden via DispatchQueue, en de compiler controleerde niet of dit veilig was. Sendable dicht deze leemte: nu volgt de compiler zelf inter-thread verzendingen en blokkeert onveilige. Dit maakt concurrente code nog voor uitvoering betrouwbaarder.

swift
struct UserProfile: Sendable {
    let name: String
    let age: Int
}

class NonSendableClass {
    var counter: Int = 0
}

In het voorbeeld kan UserProfile veilig tussen threads worden verzonden, omdat het een structuur is met constante eigenschappen van Sendable-typen. NonSendableClass zal een compilatiefout veroorzaken bij poging tot verzending via await of in Task.

Welke typen voldoen standaard aan Sendable

Sendable-typen in Swift vallen in drie categorieën: waardetypen met Sendable-eigenschappen, finale klassen met onveranderlijke toestand en functies/closures gemarkeerd met @Sendable. De compiler leidt automatisch Sendable-conformiteit af voor waardetypen.

Waardetypen en automatische conformiteit

Struct, enum en tuple worden automatisch Sendable als al hun eigenschappen en bijbehorende waarden ook Sendable zijn. Dit is een conservatieve benadering: als zelfs één eigenschap niet aan Sendable voldoet, wordt het hele type niet als veilig beschouwd.

TypeSendableVoorwaarde
StructJa (zonder expliciete vermelding)Alle eigenschappen Sendable
EnumJa (zonder expliciete vermelding)Alle bijbehorende waarden Sendable
Final classJa (met expliciete vermelding)Alle let-eigenschappen Sendable, geen var
Non-final classNeeKan niet Sendable zijn vanwege overerving

Basis typen

Alle ingebouwde Swift-typen — Int, String, Double, Bool, Optional, Array, Dictionary, Set — voldoen aan Sendable. Dit maakt typecompositie standaard veilig. De ontwikkelaar hoeft alleen op aangepaste klassen te letten.

Sendable en klassen: @unchecked Sendable

@unchecked Sendable — is een mechanisme waarmee een klasse zich expliciet als Sendable kan verklaren, waarbij compilatorcontroles worden omzeild. De ontwikkelaar neemt de verantwoordelijkheid voor de draadveiligheid van een dergelijke klasse op zich. Dit is nuttig voor Objective-C-bruggen en geoptimaliseerde structuren.

Wanneer @unchecked Sendable gebruiken

@unchecked Sendable wordt toegepast wanneer een klasse intern veiligheid garandeert via vergrendelingen of atomaire bewerkingen, maar de compiler dit niet statisch kan controleren. Bijvoorbeeld een klasse met os_unfair_lock of pthread_mutex_t — de draadveiligheid wordt door code gegarandeerd, maar Swift ziet dit niet.

swift
final class AtomicCounter: @unchecked Sendable {
    private var value: Int = 0
    private let lock = NSLock()
    
    func increment() {
        lock.lock()
        value += 1
        lock.unlock()
    }
}

Gebruik @unchecked Sendable voorzichtig. Dit is een duidelijk signaal voor andere ontwikkelaars: „ik heb het gecontroleerd, het is veilig”. Een fout in de implementatie kan leiden tot moeilijk te traceren races. Voordat u @unchecked toepast, moet u ervoor zorgen dat het type echt niet kan worden herschreven als waardetype.

Sendable in combinatie met Actor

Actor en Sendable zijn twee kanten van dezelfde medaille. Actor isoleert zijn toestand, maar voor gegevensuitwisseling met de buitenwereld moet hij Sendable-typen retourneren. Als een actormethode een niet-Sendable type retourneert, geeft de compiler een waarschuwing of fout.

Gegevensoverdracht via Sendable

Wanneer een actor gegevens naar externe code verzendt, overschrijden deze gegevens de isolatiegrens. Sendable garandeert dat de ontvanger ze veilig buiten de actor kan gebruiken. De actor zelf blijft geïsoleerd — zijn interne toestand wordt niet onthuld.

swift
struct AccountSnapshot: Sendable {
    let id: UUID
    let balance: Double
    let lastUpdated: Date
}

actor BankActor {
    private var balance: Double = 0
    
    func snapshot() async -> AccountSnapshot {
        return AccountSnapshot(
            id: UUID(),
            balance: balance,
            lastUpdated: Date()
        )
    }
}

AccountSnapshot — is een Sendable-structuur die alleen let-eigenschappen van Sendable-typen bevat. Deze benadering is best practice voor het extraheren van gegevens uit een actor. De momentopname van de toestand wordt op waarde verzonden en de actor verliest geen controle over zijn toestand.

Sendable functies en closures

@Sendable — is een attribuut voor functies en closures dat garandeert dat de closure geen niet-Sendable gegevens op een muteerbare manier vastlegt. Wanneer een closure naar Task of een actormethode wordt verzonden, moet deze Sendable zijn.

Controle van vastlegging in @Sendable closures

De compiler controleert of de @Sendable closure geen muteerbare verwijzingen naar klassen vastlegt. Het vastleggen van let-eigenschappen van Sendable-typen is toegestaan. Het vastleggen van een var-variabele van een referentietype zal een fout veroorzaken, omdat de closure gelijktijdig met mutatie kan worden uitgevoerd.

swift
func performAsync(operation: @Sendable () -> Void) {
    Task {
        await operation()
    }
}

let constant = "Safe"
var counter = 0
// counter — var vastleggen muteert teller, compilatiefout
performAsync { // ❌ Mutatie van vastgelegde var
    print(constant)
}

De regel is eenvoudig: een @Sendable closure kan alleen gegevens vastleggen die zelf Sendable zijn en niet van buitenaf worden gemuteerd. Voor klassen is het vastleggen van een weak self verwijzing toegestaan als de klasse niet als Sendable is gemarkeerd. Dit voorkomt klassieke retain cycles en race conditions.

Veelgestelde vragen

Wat is Sendable in Swift in eenvoudige woorden?

Sendable — is een marker die tegen de compiler zegt: „dit type kan veilig tussen threads worden verzonden”. Structuren en constanten zijn meestal standaard Sendable, klassen — niet, tenzij dit expliciet is aangegeven.

Welke typen voldoen automatisch aan Sendable?

Waardetypen (struct, enum) met Sendable-eigenschappen, finale klassen met onveranderlijke toestand, evenals alle basis Swift-typen: Int, String, Double, Bool, Array, Dictionary, Optional — voldoen automatisch aan Sendable.

Wat is @unchecked Sendable?

@unchecked Sendable — is een manier om een klasse als Sendable te verklaren zonder statische compilatorcontrole. De ontwikkelaar garandeert de veiligheid zelf, vaak via vergrendelingen of atomaire bewerkingen.

Waarom is Sendable nodig voor Actor?

Actor isoleert zijn toestand, maar bij het retourneren van gegevens aan externe code overschrijden deze gegevens de isolatiegrens. Sendable garandeert dat de ontvanger geen races tegenkomt bij het gebruik van deze gegevens buiten de actor.

Hoe maak je een klasse Sendable in Swift?

Voeg het Sendable-protocol toe aan een finale klasse waarvan alle eigenschappen constanten van Sendable-typen zijn. Als de klasse vergrendelingen gebruikt, kan @unchecked Sendable worden toegepast, maar dit vereist voorzichtigheid.

Samenvatting

  • Sendable — markerprotocol voor veilige gegevensoverdracht tussen threads
  • Waardetypen voldoen automatisch aan Sendable onder bepaalde voorwaarden
  • Klassen vereisen expliciete vermelding van Sendable of @unchecked Sendable
  • Actor retourneert gegevens aan externe code alleen via Sendable-typen
  • @Sendable closure-attribuut controleert de juistheid van variabele vastlegging
  • Compiler controleert statisch de conformiteit met Sendable, waardoor races in de bouwfase worden voorkomen

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook