Actor — was es ist, Datenisolierung und Nebenläufigkeit

Autor: IT Sectr Veröffentlicht: 2026-06-18 Lesezeit: 11 Min.

Actor ist ein in Swift 5.5+ eingeführter Typ, der das Problem von Datenwettläufen auf Sprachebene löst. Im Gegensatz zu manuellen Sperren und DispatchQueue-Warteschlangen isoliert ein Actor automatisch seinen Zustand und synchronisiert den Zugriff darauf. Das bedeutet, dass zwei Threads nicht gleichzeitig dieselbe Eigenschaft eines Actor-Typs ändern können, wodurch Wettlaufsituationen ohne zusätzlichen Aufwand des Entwicklers vermieden werden. Der Mechanismus basiert auf dem Konzept der Actor-Isolierung, bei dem der Compiler den Zugriff auf Actor-Eigenschaften und -Methoden verfolgt. Laut Apple, 2025 ist das Actor-Modell ein grundlegender Bestandteil des Nebenläufigkeitssystems von Swift.

Wichtige Punkte

  • Actor ist ein Typ, der seinen Zustand automatisch auf Compiler-Ebene vor Datenwettläufen isoliert
  • Isolierung garantiert, dass jeweils nur ein Thread auf die Actor-Instanz zugreift
  • Aufrufe von Actor-Methoden werden asynchron über den async/await-Mechanismus ausgeführt
  • Nonisolated ermöglicht das selektive Deaktivieren der Isolierung für einzelne Actor-Member
  • Reentrancy erlaubt den Wiedereintritt in einen Actor und verhindert so Deadlocks

Was ist ein Actor in Swift?

Actor ist ein Referenztyp, ähnlich einer Klasse, aber mit automatischem Schutz vor Datenwettläufen. Er wurde in Swift 5.5 als Teil des Nebenläufigkeitssystems zusammen mit async/await und Task eingeführt. Ein Actor garantiert, dass sein veränderlicher Zustand nie gleichzeitig von verschiedenen Threads ohne explizite Synchronisation gelesen oder geschrieben wird.

Actor-Deklarationssyntax

Um einen Actor zu deklarieren, wird das Schlüsselwort actor gefolgt von geschweiften Klammern mit seinen Membern verwendet. Syntaktisch ähnelt ein Actor einer Klasse, aber sein Verhalten unterscheidet sich grundlegend.

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

Der Compiler isoliert automatisch alle Actor-Eigenschaften und -Methoden, sodass sie nur innerhalb des Actor-Kontexts zugänglich sind. Beim Versuch, von außerhalb des Actors auf balance zuzugreifen, erzeugt der Compiler einen Fehler, wenn der Aufruf nicht als async markiert ist.

Wie funktioniert die Datenisolierung in Actor

Datenisolierung ist das Schlüsselkonzept eines Actors. Ein Actor garantiert den wechselseitig ausschließlichen Zugriff auf seinen Zustand über den Actor-Executor-Mechanismus. Jeder Actor hat seinen eigenen Executor, der alle Zugriffe auf seine isolierten Member sequentiell verarbeitet.

Wie die Isolierung funktioniert

Wenn Code außerhalb eines Actors seine Methode aufruft, wird der Aufruf in die Warteschlange des Actor-Executors gestellt. Der Actor führt jeweils nur eine Aufgabe aus und garantiert so das Fehlen von Wettläufen. Wenn zwei Threads gleichzeitig deposit aufrufen, wartet der zweite Aufruf auf den Abschluss des ersten.

swift
let account = BankAccount(initialBalance: 1000.0)
// Asynchroner Aufruf — von außerhalb des Actors erforderlich
await account.deposit(amount: 500.0)
let currentBalance = await account.getBalance()

Jeder Aufruf einer Actor-Methode erfordert await, weil der Actor möglicherweise mit einer anderen Aufgabe beschäftigt ist. Dies ist kein Fehler, sondern ein bewusstes Design, das Wettläufe verhindert. Swift macht implizit die Getter und Setter von Actor-Eigenschaften async, daher erfordert auch das Lesen einer Eigenschaft await.

Hauptunterschiede zwischen Actor und Klasse

Actor und Klasse sind beide Referenztypen, aber ihr Verhalten in einer Multithread-Umgebung unterscheidet sich drastisch. Eine Klasse bietet keinen automatischen Schutz vor Wettläufen, während ein Actor diesen auf Compiler-Ebene durch das Typsystem einbettet.

MerkmalActorKlasse
WettlaufschutzAutomatisch, auf Compiler-EbeneErfordert manuelle Synchronisation
EigenschaftszugriffNur über await von außenDirekt, ohne Synchronisation
VererbungNur von anderen ActorsStandard klassenbasiert
ProtokollkonformitätKann Protokollen entsprechenStandard
LeistungGeringer Overhead bei IsolierungSchneller ohne Synchronisation

Actor-Vererbung

Ein Actor kann nur von einem anderen Actor erben und nicht von einer Klasse. Dies ist beabsichtigt, weil einer Klasse der Actor-Isolierungs-Mechanismus fehlt und das Mischen von Typen die Sicherheitsgarantien brechen würde.

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

Asynchrone Aufrufe von Actor-Methoden

Asynchrone Aufrufe sind der Mechanismus zur Interaktion mit einem Actor aus externem Code. Da ein Actor seinen Zustand isoliert, erfordert jeder Zugriff auf seine Member von außen await. Dadurch kann Swift garantieren, dass der aufrufende Code den Thread nicht blockiert und der Actor andere Anfragen verarbeiten kann.

Globale und lokale Actors

Neben deklarierten Actor-Typen unterstützt Swift globale Actors — das @MainActor-Attribut, das Klassen, Eigenschaften oder Methoden als auf dem Hauptthread ausführbar markiert. Dies ist besonders nützlich für UI-Code in iOS-Anwendungen.

swift
@MainActor
class ViewModel: ObservableObject {
    @Published var title: String = ""
    
    func updateTitle() {
        // Dieser Code wird garantiert auf dem Hauptthread ausgeführt
        title = "New Title"
    }
}

Die Verwendung von @MainActor macht den manuellen Aufruf von DispatchQueue.main.async überflüssig und macht den Code sauberer und sicherer. Der Compiler stellt sicher, dass der Wechsel zum Hauptthread korrekt erfolgt.

Nonisolated und Actor-Isolated Kontexte

Nonisolated ist ein Schlüsselwort, mit dem eine Methode oder berechnete Eigenschaft eines Actors als nicht isoliert markiert werden kann. Solche Member haben keinen Zugriff auf den isolierten Zustand des Actors, können aber von außerhalb des Actors ohne await aufgerufen werden.

Nonisolated Funktionen

Nonisolated Methoden sind nützlich für Berechnungen, die nicht vom veränderlichen Zustand des Actors abhängen. Beispielsweise greift die Methode formatBalance nicht direkt auf balance zu, sondern formatiert nur den übergebenen Wert — eine solche Methode kann sicher nonisolated gemacht werden.

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

Nonisolated Member werden synchron ausgeführt und benötigen kein await. Sie können jedoch nicht direkt auf Actor-isolierte Eigenschaften zugreifen. Wenn eine nonisolated Methode einen Wert vom Actor benötigt, muss dieser als Parameter übergeben werden.

Reentrancy und Wiedereintritt

Reentrancy ist ein Mechanismus, der den Wiedereintritt in einen Actor während des Wartens auf einen asynchronen Aufruf ermöglicht. Ohne Reentrancy könnte ein Actor für immer blockieren, wenn eine seiner Methoden auf eine andere wartet, die wiederum auf die erste wartet.

Wie Reentrancy funktioniert

Wenn Code innerhalb eines Actors await ausführt, unterbricht der Actor die aktuelle Aufgabe und kann eine andere in der Warteschlange befindliche Aufgabe verarbeiten. Nach Abschluss von await wird die Aufgabe fortgesetzt. Dies verhindert Deadlocks, erfordert jedoch Vorsicht: Der Actor-Zustand zwischen await-Punkten kann sich ändern.

swift
actor DataProcessor {
    var cache: [Int: String] = [:]
    
    func process(id: Int) async -> String {
        if let cached = cache[id] {
            return cached
        }
        // await — Wiedereintrittspunkt
        let result = await fetchData(id: id)
        // Der Cache könnte sich nach await geändert haben — erneut prüfen
        cache[id] = result
        return result
    }
}

Entwickler müssen Reentrancy berücksichtigen und den Actor-Zustand nach await-Punkten überprüfen. Ein typischer Fehler ist die Annahme, dass die Actor-Isolierung über asynchrone Unterbrechungspunkte hinweg bestehen bleibt. In der Praxis kann der Zustand zwischen await und der nächsten Anweisung vom Erwarteten abweichen.

Häufig gestellte Fragen

Wie unterscheidet sich Actor von einer Klasse in Swift?

Actor isoliert automatisch seinen Zustand vor Datenwettläufen und erfordert await für den externen Zugriff. Eine Klasse bietet keinen solchen Schutz — der Entwickler ist für die Synchronisation über Sperren oder Warteschlangen verantwortlich. Ein Actor erbt nur von einem Actor, eine Klasse von einer Klasse.

Kann man von einem Actor erben?

Ja, ein Actor kann von einem anderen Actor erben. Die Unterklasse erhält alle isolierten Eigenschaften und Methoden des Elternobjekts. Ein Actor kann nicht von einer Klasse erben, da Klassen den Actor-Isolierungsmechanismus auf Compiler-Ebene nicht besitzen.

Was ist ein Actor-isolated Kontext?

Ein actor-isolated Kontext ist ein Codebereich, in dem der direkte Zugriff auf den veränderlichen Zustand des Actors erlaubt ist. Innerhalb von Actor-Methoden, die als isoliert markiert sind (standardmäßig), können Eigenschaften ohne await gelesen und geschrieben werden. Der Compiler überprüft die Isolierungsgrenzen.

Wie übergibt man Daten von einem Actor an externen Code?

Daten von einem Actor werden über async-Methoden übergeben, die Sendable-Typen zurückgeben, oder über nonisolated Methoden, die Werte als Parameter akzeptieren. Man kann auch eine async-Eigenschaft erstellen, die einen Snapshot des Actor-Zustands als Sendable-Struktur zurückgibt.

Unterstützt Actor die Protokollkonformität?

Ja, ein Actor kann Protokollen entsprechen. Wenn ein Protokoll isolierte Anforderungen (actor-isolated) enthält, werden diese automatisch Actor-isoliert. Für asynchrone Methoden in Protokollen kann mit dem isolated-Marker angegeben werden, dass sie auf einem bestimmten Actor aufgerufen werden müssen.

Zusammenfassung

  • Actor ist ein Referenztyp mit automatischer Datenisolierung, eingeführt in Swift 5.5+
  • Isolierung funktioniert über einen Actor-Executor, der Anfragen sequentiell verarbeitet
  • Externer Zugriff auf einen Actor erfordert await — dies garantiert Wettlauffreiheit
  • Nonisolated ermöglicht die Deklaration synchroner Methoden ohne Zugriff auf isolierten Zustand
  • Globale Actors (@MainActor) erweitern die Isolierung auf den gesamten Ausführungsthread
  • Reentrancy verhindert Deadlocks, indem es den Wiedereintritt in einen Actor während await erlaubt

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch