Aktor — mi ez, adatizolálás és konkurencia

Szerző: IT Sectr Megjelenés: 2026-06-18 Olvasási idő: 11 perc

Actor — egy Swift 5.5+-ban bevezetett típus, amely nyelvi szinten oldja meg az adatversenyhelyzetek problémáját. A kézi zárakkal és DispatchQueue sorokkal ellentétben az actor automatikusan izolálja állapotát és szinkronizálja a hozzáférést. Ez azt jelenti, hogy két szál nem módosíthatja egyszerre ugyanazt a tulajdonságot egy actor-típusban, ami külső erőfeszítés nélkül kúszöböli ki a versenyhelyzetet. A mechanizmus az actor-izoláció koncepcióján alapul, ahol a fordító nyomon követi az actor tulajdonságaihoz és metódusaihoz való hozzáférést. A Apple, 2025 szerint az actor modell a Swift konkurenciarendszerének alapvető része.

Főbb pontok

  • Actor — típus, amely automatikusan izolálja állapotát a versenyhelyzetektől fordítói szinten
  • Izoláció garantálja, hogy csak egy szál fér hozzá egyszerre az actor-példányhoz
  • Hívások actor metódusai aszinkron módon, async/await mechanizmuson keresztül történnek
  • Nonisolated lehetővé teszi az izoláció szelektív kikapcsolását az actor egyes tagjainál
  • Reentrancy lehetővé teszi az actorba való újbelépést, megakadályozva a kölcsönös blokkolásokat

Mi az Actor a Swiftben?

Actor — egy referenciatípus, hasonló az osztályhoz, de automatikus védelemmel a versenyhelyzetek ellen. A Swift 5.5-ben került bevezetésre a konkurenciarendszer részeként az async/await és Task mellett. Az actor garantálja, hogy változtatható állapota soha nem kerül egyidejűleg olvasásra vagy írásra különböző szálakból kifejezett szinkronizáció nélkül.

Az Actor deklarálásának szintaxisa

Az actor deklarálásához az actor kulcsszót használjuk, amelyet kapcsos zárójelek követnek a tagjaival. Szintaktikailag az actor hasonlít az osztályra, de a viselkedése győkeresen eltér.

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

A fordító automatikusan izolálja az actor összes tulajdonságát és metódusát úgy, hogy azok csak az actor-kontextuson belül érhetők el. Ha a balance-t az actoron kívülről próbáljuk elérni, a fordító hibát dob, ha a hívás nincs async-ként megjelölve.

Hogyan működik az adatizoláció az Actorban

Adatizoláció — az actor kulcsfogalma. Az actor az actor-végrehajtó (actor executor) mechanizmusán keresztül garantálja a kölcsönösen kizáró hozzáférést állapotához. Minden actor rendelkezik saját végrehajtóval, amely az izolált tagjaihoz való összes hozzáférést szekvenciálisan dolgozza fel.

Az izoláció működési elve

Amikor az actoron kívüli kód meghívja annak metódusát, a hívás az actor-végrehajtó sorába kerül. Az actor egyszerre csak egy feladatot végez, ami garantálja a versenyhelyzetek hiányát. Ha két szál egyszerre hívja a deposit-ot, a második hívás megvárja az első befejeződését.

swift
let account = BankAccount(initialBalance: 1000.0)
// Aszinkron hívás — az actoron kívülről szükséges
await account.deposit(amount: 500.0)
let currentBalance = await account.getBalance()

Az actor metódusának minden hívása await-et igényel, mert az actor más feladattal lehet elfoglalva. Ez nem hiba, hanem tudatos tervezés a versenyhelyzetek elkerülésére. A Swift implicit módon aszinkronná teszi az actor tulajdonságainak getter-jeit és setter-eit, így egy tulajdonság olvasása is await-et igényel.

Fő különbségek az Actor és az osztály között

Actor és osztály referenciatípusok, de viselkedésük többszálas környezetben győkeresen eltér. Az osztály nem nyújt semmilyen automatikus védelmet a versenyhelyzetek ellen, míg az actor beépíti azt fordítói szinten a típusrendszeren keresztül.

JellemzőActorClass
Védelem a versenyhelyzet ellenAutomatikus, fordítói szintenKézi szinkronizációt igényel
Hozzáférés tulajdonságokhozCsak await-en keresztül külrőlKözvetlen, szinkronizáció nélkül
ÖröklésCsak más actoroktólSzabvány osztályöröklés
Protokoll megfelelésKépes protokolloknak megfelelniSzabvány
TeljesítményAlacsony többletterhelés izolációnálSzinkronizáció nélkül — gyorsabb

Az Actor öröklése

Az actor csak másik actor-tól örökődhet, és nem örökődhet osztályból. Ez tudatosan történt így, mert az osztály nem rendelkezik az actor-izoláció mechanizmusával, és a két modell keverése meghatározatlan viselkedéshez vezetne.

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

Actor metódusok aszinkron hívásai

Aszinkron hívások — az actorral való interakció mechanizmusa külső kódból. Mivel az actor izolálja állapotát, minden külső hozzáférés a tagjaihoz await-et igényel. Ez lehetővé teszi a Swift számára, hogy garantálja: a hívó kód nem blokkolja a szálat, és az actor más kéréseket is feldolgozhat.

Globális és lokális actorok

A deklarált actor-típusok mellett a Swift támogatja a globális actorokat — a @MainActor attribútumot, amely osztályokat, tulajdonságokat vagy metódusokat jelöl meg a főszálon való végrehajtásra. Ez különösen hasznos UIKit és SwiftUI használata esetén.

swift
@MainActor
class ViewModel: ObservableObject {
    @Published var title: String = ""
    
    func updateTitle() {
        // Ez a kód garantáltan a főszálon fut
        title = "New Title"
    }
}

A @MainActor használata kiküzöböli a DispatchQueue.main.async kézi meghívásának szükségességét, ami tisztábbá és biztonságosabbá teszi a kódot. A fordító ellenőrzi, hogy a főszálra váltás helyesen történik-e.

Nonisolated és actor-isolated kontextusok

Nonisolated — egy kulcsszó, amely lehetővé teszi egy actor metódusának vagy számított tulajdonságának nem-izoláltként való megjelölését. Az ilyen tagok nem férnek hozzá az actor izolált állapotához, de await nélkül hívhatók az actoron kívülről.

Nonisolated függvények

A nonisolated metódusok hasznosak olyan számításokhoz, amelyek nem függnek az actor változtatható állapotától. Például a formatBalance metódus nem fér közvetlenül hozzá a balance-hoz, csak formázza az átadott értéket — egy ilyen metódus biztonságosan nonisolateddá tehető.

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

A nonisolated tagok szinkron módon hajtódnak végre, és nem igényelnek await-et. Azonban nem tudják közvetlenül olvasni az actor izolált tulajdonságait. Ha egy nonisolated metódusnak értékre van szüksége az actor-ból, azt paraméterként kell átadni.

Reentrancy és újbelépés

Reentrancy — egy mechanizmus, amely lehetővé teszi az actorba való újbelépést aszinkron hívás várakozása közben. Reentrancy nélkül az actor örökre blokkolódhatna, ha az egyik metódusa egy másikra várna, ami viszont az elsőre vár.

Hogyan működik a reentrancy

Amikor az actoron belüli kód await-et hajt végre, az actor felfüggeszti az aktuális feladatot, és feldolgozhat egy másikat, amely a sorban van. Az await befejeződése után a feladat folytatódik. Ez megakadályozza a deadlock-okat, de óvatosságot igényel: az actor állapota az await pontok között megváltozhat.

swift
actor DataProcessor {
    var cache: [Int: String] = [:]
    
    func process(id: Int) async -> String {
        if let cached = cache[id] {
            return cached
        }
        // await — újbelépési pont
        let result = await fetchData(id: id)
        // A gyorsitótár megváltozhatott await után — ellenőrizze újra
        cache[id] = result
        return result
    }
}

A fejlesztőknek figyelembe kell venniük a reentrancy-t, és ellenőrizniük kell az actor állapotát az await pontok után. Tipikus hiba annak feltételezése, hogy az actor-izoláció az aszinkron szünetek során is fennmarad. A gyakorlatban az await és a következő utasítás között az állapot eltérhet a várttól.

Gyakran Ismételt Kérdések

Miben különbözik az Actor az osztálytól a Swiftben?

Actor automatikusan izolálja állapotát a versenyhelyzetektől, await-et igényelve a külső hozzáféréshez. Az osztály nem nyújt ilyen védelmet — a fejlesztő maga felel a szinkronizációért zárak és sorok segítségével. Az actor csak actor-tól örökődik, az osztály osztálytól.

Lehet öröklődni Actor-ból?

Igen, az actor örökődhet másik actor-ból. Az alosztály megkapja a szülő összes izolált tulajdonságát és metódusát. Az actor nem örökődhet osztályból, mert az osztályok nem rendelkeznek actor-izolációs mechanizmussal fordítói szinten.

Mi az az actor-isolated kontextus?

Actor-isolated kontextus — az a kódterüelet, ahol engedélyezett a közvetlen hozzáférés az actor változtatható állapotához. Az actor isolatedként megjelölt (alapértelmezett) metódusain belül a tulajdonságok await nélkül olvashatók és írhatók. A fordító ellenőrzi az izolációs határokat.

Hogyan lehet adatokat átadni az Actor-ból külső kódnak?

Az actor adatait async-metódusokon keresztül adjuk át, amelyek Sendable típusokat adnak vissza, vagy nonisolated metódusokon keresztül, amelyek értékeket fogadnak paraméterként. Létrehozható egy async tulajdonság is, amely az actor állapotának pillanatképét adja vissza Sendable struktúra formájában.

Támogatja az Actor a protokollöröklést?

Igen, az actor képes protokolloknak megfelelni. Ha a protokoll izolált követelményeket (actor-isolated) tartalmaz, azok automatikusan actor-izolálttá válnak. A protokollok aszinkron metódusaihoz az isolated marker segítségével megadható, hogy egy adott actor-on kell őket meghívni.

Összefoglaló

  • Actor — referenciatípus automatikus adatizolációval, bevezetve a Swift 5.5+-ban
  • Izoláció az actor-végrehajtón keresztül működik, amely szekvenciálisan dolgozza fel a kéréseket
  • Külső hozzáférés az actorhoz await-et igényel — ez garantálja a versenyhelyzetek hiányát
  • Nonisolated lehetővé teszi szinkron metódusok deklarálását, amelyek nem férnek hozzá az izolált állapothoz
  • Globális actorok (@MainActor) az izolációt a teljes végrehajtási szálra terjesztik ki
  • Reentrancy megakadályozza a deadlock-okat azáltal, hogy lehetővé teszi az újbelépést az actorba await alatt

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is