Actor — wat is het, gegevensisolatie en concurrency

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

Actor — is een type geïntroduceerd in Swift 5.5+ dat het probleem van race conditions op taalniveau oplost. In tegenstelling tot handmatige vergrendelingen en DispatchQueue-wachtrijen, isoleert een actor automatisch zijn status en synchroniseert de toegang ernaartoe. Dit betekent dat twee threads niet tegelijkertijd dezelfde eigenschap van een actortype kunnen wijzigen, wat race conditions uitsluit zonder extra inspanning van de ontwikkelaar. Het mechanisme is gebaseerd op het concept van actor-isolatie, waarbij de compiler toegang tot eigenschappen en methoden van de actor controleert. Volgens Apple, 2025 is het actormodel een fundamenteel onderdeel van het concurrency-systeem van Swift.

Belangrijkste punten

  • Actor — type dat automatisch zijn status isoleert van race conditions op compilerniveau
  • Isolatie garandeert dat slechts één thread tegelijkertijd toegang heeft tot de actor-instantie
  • Aanroepen van actormethoden worden asynchroon uitgevoerd via het async/await-mechanisme
  • Nonisolated maakt het mogelijk isolatie selectief uit te schakelen voor individuele leden van de actor
  • Reentrancy staat herhaalde toegang tot de actor toe, waardoor wederzijdse blokkades worden voorkomen

Wat is Actor in Swift?

Actor — is een referentietype, vergelijkbaar met een klasse, maar met automatische bescherming tegen race conditions. Het werd geïntroduceerd in Swift 5.5 als onderdeel van het concurrency-systeem naast async/await en Task. Een actor garandeert dat zijn veranderlijke status nooit gelijktijdig wordt gelezen of geschreven vanuit verschillende threads zonder expliciete synchronisatie.

Syntaxis voor het declareren van een Actor

Om een actor te declareren wordt het sleutelwoord actor gebruikt, gevolgd door accolades met zijn leden. Qua syntaxis lijkt een actor op een klasse, maar het gedrag is radicaal anders.

swift
actor BankAccount {
    private var balance: Double
    
    init(initialBalance: Double) {
        self.balance = initialBalance
    }
    
    func deposit(amount: Double) {
        balance += amount
    }
    
    func getBalance() -> Double {
        return balance
    }
}

De compiler isoleert automatisch alle eigenschappen en methoden van de actor, zodat ze alleen binnen de actorcontext toegankelijk zijn. Een poging om balance van buiten de actor te benaderen, resulteert in een compilatiefout als de aanroep niet is gemarkeerd als async.

Hoe gegevensisolatie in Actor werkt

Gegevensisolatie — is het belangrijkste concept van de actor. De actor garandeert wederzijds exclusieve toegang tot zijn status via het mechanisme van de actoruitvoerder (actor executor). Elke actor heeft zijn eigen uitvoerder die alle toegangen tot zijn geïsoleerde leden sequentieel verwerkt.

Werkingsprincipe van isolatie

Wanneer code buiten de actor zijn methode aanroept, wordt de aanroep in de wachtrij van de actoruitvoerder geplaatst. De actor voert slechts één taak tegelijk uit, wat de afwezigheid van race conditions garandeert. Als twee threads tegelijkertijd deposit aanroepen, wacht de tweede aanroep op voltooiing van de eerste.

swift
let account = BankAccount(initialBalance: 1000.0)
// Asynchrone aanroep — vereist van buiten de actor
await account.deposit(amount: 500.0)
let currentBalance = await account.getBalance()

Elke aanroep van een actormethode vereist await, omdat de actor mogelijk bezig is met een andere taak. Dit is geen bug, maar een bewust ontwerp om race conditions te voorkomen. Swift maakt getters en setters van actoreigenschappen impliciet async, dus het lezen van een eigenschap vereist ook await.

Belangrijkste verschillen tussen Actor en klasse

Actor en klasse zijn referentietypen, maar hun gedrag in een multi-threaded omgeving verschilt radicaal. Een klasse biedt geen enkele automatische bescherming tegen race conditions, terwijl een actor deze op compilerniveau inbouwt via het typesysteem.

KenmerkActorClass
Bescherming tegen racesAutomatisch, op compilerniveauVereist handmatige synchronisatie
Toegang tot eigenschappenAlleen via await van buitenafDirect, zonder synchronisatie
OverervingAlleen van andere actorsStandaard klasse-overerving
ProtocolconformiteitKan voldoen aan protocollenStandaard
PrestatiesLage overhead bij isolatieZonder synchronisatie — sneller

Overerving van Actor

Een actor kan alleen overerven van een andere actor en niet van een klasse. Dit is bewust gedaan, omdat een klasse geen mechanisme voor actorisolatie heeft en het mengen van twee modellen zou leiden tot ongedefinieerd gedrag.

swift
actor SavingsAccount: BankAccount {
    func applyInterest(rate: Double) {
        let interest = balance * rate
        balance += interest
    }
}

Asynchrone aanroepen van Actormethoden

Asynchrone aanroepen — zijn het mechanisme voor interactie met de actor vanuit externe code. Omdat de actor zijn status isoleert, vereist elke toegang tot zijn leden van buitenaf await. Dit stelt Swift in staat te garanderen dat de aanroepende code de thread niet blokkeert en de actor andere verzoeken kan verwerken.

Globale en lokale actors

Naast gedeclareerde actortypen ondersteunt Swift globale actors — het @MainActor-attribuut, dat klassen, eigenschappen of methoden markeert als uitgevoerd op de hoofdthread. Dit is vooral handig bij het werken met UIKit en SwiftUI.

swift
@MainActor
class ViewModel: ObservableObject {
    @Published var title: String = ""
    
    func updateTitle() {
        // Deze code wordt gegarandeerd op de hoofdthread uitgevoerd
        title = "New Title"
    }
}

Het gebruik van @MainActor elimineert de noodzaak om handmatig DispatchQueue.main.async aan te roepen, wat de code schoner en veiliger maakt. De compiler controleert of de overschakeling naar de hoofdthread correct plaatsvindt.

Nonisolated en actor-isolated contexten

Nonisolated — is een sleutelwoord waarmee een methode of berekende eigenschap van een actor als niet-geïsoleerd kan worden gemarkeerd. Dergelijke leden hebben geen toegang tot de geïsoleerde status van de actor, maar kunnen van buiten de actor worden aangeroepen zonder await.

Nonisolated functies

Nonisolated methoden zijn nuttig voor berekeningen die niet afhankelijk zijn van de veranderlijke status van de actor. De methode formatBalance heeft bijvoorbeeld geen directe toegang tot balance, maar formatteert alleen de doorgegeven waarde — zo'n methode kan veilig nonisolated worden gemaakt.

swift
actor BankAccount {
    private var balance: Double = 0
    
    nonisolated func formatBalance(amount: Double) -> String {
        return "$\(amount)"
    }
}

Nonisolated leden worden synchroon uitgevoerd en vereisen geen await. Ze kunnen echter niet direct de geïsoleerde eigenschappen van de actor lezen. Als een nonisolated methode een waarde uit de actor nodig heeft, moet deze als parameter worden doorgegeven.

Reentrancy en herhaalde toegang

Reentrancy — is een mechanisme dat herhaalde toegang tot de actor mogelijk maakt tijdens het wachten op een asynchrone aanroep. Zonder reentrancy zou de actor voor altijd kunnen blokkeren als een van zijn methoden op een andere wacht, die op zijn beurt op de eerste wacht.

Hoe reentrancy werkt

Wanneer code binnen de actor await uitvoert, onderbreekt de actor de huidige taak en kan hij een andere verwerken die in de wachtrij staat. Na voltooiing van await wordt de taak hervat. Dit voorkomt deadlocks, maar vereist voorzichtigheid: de status van de actor tussen await-punten kan veranderen.

swift
actor DataProcessor {
    var cache: [Int: String] = [:]
    
    func process(id: Int) async -> String {
        if let cached = cache[id] {
            return cached
        }
        // await — herintredingspunt
        let result = await fetchData(id: id)
        // Cache kan zijn veranderd na await — controleer opnieuw
        cache[id] = result
        return result
    }
}

Ontwikkelaars moeten rekening houden met reentrancy en de status van de actor controleren na await-punten. Een veelgemaakte fout is de veronderstelling dat actorisolatie behouden blijft tijdens asynchrone pauzes. In de praktijk kan de status tussen await en de volgende instructie afwijken van de verwachte.

Veelgestelde vragen

Waarin verschilt Actor van een klasse in Swift?

Actor isoleert automatisch zijn status van race conditions en vereist await voor toegang van buitenaf. Een klasse biedt geen dergelijke bescherming — de ontwikkelaar is zelf verantwoordelijk voor synchronisatie via vergrendelingen of wachtrijen. Een actor erft alleen over van een actor, een klasse van een klasse.

Kan men overerven van een Actor?

Ja, een actor kan overerven van een andere actor. De subklasse krijgt alle geïsoleerde eigenschappen en methoden van de ouder. Een actor kan niet overerven van een klasse, omdat klassen geen mechanisme voor actorisolatie op compilerniveau hebben.

Wat is een actor-isolated context?

Actor-isolated context — is een codegebied waarin directe toegang tot de veranderlijke status van de actor is toegestaan. Binnen methoden van de actor die als isolated (standaard) zijn gemarkeerd, kunnen eigenschappen worden gelezen en geschreven zonder await. De compiler controleert de isolatiegrenzen.

Hoe gegevens van Actor naar externe code doorgeven?

Gegevens van de actor worden doorgegeven via async-methoden die Sendable-typen retourneren, of via nonisolated methoden die waarden als parameters accepteren. Men kan ook een async-eigenschap maken die een momentopname van de actorstatus retourneert in de vorm van een Sendable-structuur.

Ondersteunt Actor overerving van protocollen?

Ja, een actor kan voldoen aan protocollen. Als het protocol geïsoleerde vereisten (actor-isolated) bevat, worden deze automatisch actor-geïsoleerd. Voor asynchrone methoden in protocollen kan met de isolated-marker worden aangegeven dat ze op een specifieke actor moeten worden aangeroepen.

Samenvatting

  • Actor — referentietype met automatische gegevensisolatie, geïntroduceerd in Swift 5.5+
  • Isolatie werkt via de actoruitvoerder die verzoeken sequentieel verwerkt
  • Externe toegang tot de actor vereist await — dit garandeert de afwezigheid van races
  • Nonisolated maakt het mogelijk synchrone methoden te declareren die geen toegang hebben tot de geïsoleerde status
  • Globale actors (@MainActor) breiden isolatie uit over de hele uitvoeringsthread
  • Reentrancy voorkomt deadlocks door herhaalde toegang tot de actor tijdens await toe te staan

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