Актор — шта је, изолација података и конкурентност

Аутор: IT Sectr Објављено: 2026-06-18 Време читања: 11 мин

Actor — је тип представљен у Swift 5.5+ који решава проблем трке података на нивоу језика. За разлику од ручних блокада и редова DispatchQueue, actor аутоматски изолише своје стање и синхронизује приступ њему. То значи да две нити не могу истовремено изменити исто својство типа actor, што елиминише стање трке без додатног напора развојача. Механизам се заснива на концепту изолације актора, када компилер прати приступ својствима и методама actor-а. Према Apple, 2025, модел актора је фундаментални део система конкурентности Swift-а.

Главно

  • Actor — тип који аутоматски изолише своје стање од трке података на нивоу компилера
  • Изолација гарантује да само једна нит истовремено приступа инстанци actor-а
  • Позиви метода actor-а се извршавају асинхроно кроз механизам async/await
  • Nonisolated омогућава селективно искључивање изолације за појединачне чланове actor-а
  • Reentrancy омогућава поновни улазак у actor, спречавајући медусобне блокаде

Шта је Actor у Swift-у?

Actor — је референцни тип, сличан класи, али са аутоматском заштитом од трке података. Представљен је у Swift 5.5 као део система конкурентности заједно са async/await и Task. Actor гарантује да његово промењиво стање никада неће бити истовремено прочитано или записано из различитих нити без експлицитне синхронизације.

Синтакса декларације Actor

За декларацију actor-а користи се кључна реч actor, након чега следе витичасте заграде са његовим члановима. Синтаксички, actor подсећа на класу, али понашање је радикално другачије.

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

Компилер аутоматски изолише сва својства и методе actor-а тако да постају доступни само унутар контекста actor-а. Покушај приступа balance-у изван actor-а ће произвести грешку компилера ако позив није означен као async.

Како ради изолација података у Actor-у

Изолација података — је кључни концепт actor-а. Actor гарантује међусобно искључив приступ свом стању кроз механизам извршиоца actor-а (actor executor). Сваки actor има сопственог извршиоца који обрађује све приступе његовим изолованим члановима секвенцијално.

Принцип рада изолације

Када код изван actor-а позива његову методу, позив се ставља у ред извршиоца actor-а. Actor извршава само један задатак истовремено, што гарантује одсуство трке. Ако две нити истовремено позову deposit, други позив чека завршетак првог.

swift
let account = BankAccount(initialBalance: 1000.0)
// Asinhroni poziv — zahtevan izvan actor-a
await account.deposit(amount: 500.0)
let currentBalance = await account.getBalance()

Сваки позив методе actor-а захтева await, јер би actor могао бити заузет другим задатком. То није грешка, већ свесни дизајн који спречава трку. Swift имплицитно чини гетере и сетере својстава actor-а async, па читање својства такође захтева await.

Основне разлике између Actor-а и класе

Actor и класа су референцни типови, али њихово понашање у вишенитном окружењу се радикално разликује. Класа не пружа никакву аутоматску заштиту од трке, док actor је уграђује на нивоу компилера кроз систем типова.

КарактеристикаActorClass
Заштита од тркеАутоматска, на нивоу компилераЗахтева ручну синхронизацију
Приступ својствимаСамо кроз await спољаДиректан, без синхронизације
НасљеђивањеСамо од других actor-аСтандардно класно
Придржавање протоколимаМоже да се придржава протоколимаСтандардно
ПерформансеНиска прекошивност при изолацијиБез синхронизације — брже

Насљеђивање Actor

Actor може да насљеди само од другог actor-а и не може да насљеди од класе. То је урађено намерно, јер класа нема механизам изолације actor-а, и мешавина два модела би довела до недефинисаног понашања.

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

Асинхрони позиви метода Actor-а

Асинхрони позиви — су механизам интеракције са actor-ом из спољашњег кода. Пошто actor изолише своје стање, сваки приступ његовим члановима споља захтева await. То омогућава Swift-у да гарантује да позивни код не блокира нит и да actor може да обрађује друге захтеве.

Глобални и локални actorи

Поред декларисаних типова actor-а, Swift подржава глобалне actor-е — атрибут @MainActor, који означава класе, својства или методе као оне које се извршавају на главној нити. То је посебно корисно при раду са UIKit и SwiftUI.

swift
@MainActor
class ViewModel: ObservableObject {
    @Published var title: String = ""
    
    func updateTitle() {
        // Ovaj kod je garantovano izvršen na glavnoj niti
        title = "New Title"
    }
}

Коришћењем @MainActor елиминише се потреба за ручним позивом DispatchQueue.main.async, што чини код чишћим и сигурнијим. Компилер проверава да се пребацивање на главну нит одвија исправно.

Nonisolated и actor-isolated контексти

Nonisolated — је кључна реч која омогућава означавање методе или израчунатог својства actor-а као неизолованог. Такви чланови немају приступ изолованом стању actor-а, али се могу позивати без await споља actor-а.

Nonisolated функције

Nonisolated методе су корисне за израчунавања која не зависе од промењивог стања actor-а. На примјер, метода formatBalance не приступа директно balance-у, већ само форматира прослеђеђену вриједност — такву методу је сигурно могуће учинити nonisolated.

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

Nonisolated чланови се извршавају синхроно и не захтевају await. Међутим, они не могу директно да читају изоловане својства actor-а. Ако nonisolated методи треба вриједност из actor-а, она се мора проследити као параметар.

Reentrancy и поновни улазак

Reentrancy — је механизам који омогућава поновни улазак у actor током чекања асинхроног позива. Без reentrancy-ја, actor би могао заувека да се блокира ако једна његова метода чека другу која заузврат чека прву.

Како ради reentrancy

Када код унутар actor-а извршава await, actor привремено зауставља тренутни задатак и може да обради други постављен у ред. Након завршетка await-а, задатак се наставља. То спречава deadlock-е, али захтева опрезност: стање actor-а између тачака await се може променити.

swift
actor DataProcessor {
    var cache: [Int: String] = [:]
    
    func process(id: Int) async -> String {
        if let cached = cache[id] {
            return cached
        }
        // await — tačka ponovnog ulaska
        let result = await fetchData(id: id)
        // Keš se može promeniti nakon await — proveri ponovo
        cache[id] = result
        return result
    }
}

Развојачи морају да узму у обзир reentrancy и провере стање actor-а након тачака await. Типична грешка је претпоставка да се изолација actor-а одржава кроз асинхроне паузе. У пракси, између await-а и следеће инструкције, стање се може разликовати од очекиваног.

Често постављана питања

По чему се Actor разликује од класе у Swift-у?

Actor аутоматски изолише своје стање од трке података, захтевајући await за приступ споља. Класа не пружа такву заштиту — развојач сам одговара за синхронизацију кроз блокаде или редове. Actor насљеђује само од actor-а, класа од класе.

Може ли се насљедивати од Actor-а?

Да, actor може да насљеди од другог actor-а. Подкласа добија сва изолована својства и методе родитеља. Actor не може да насљеди од класе, јер класе немају механизам изолације actor-а на нивоу компилера.

Шта је actor-isolated контекст?

Actor-isolated контекст — је област кода у којој је дозвољен директан приступ промењивом стању actor-а. Унутар метода actor-а означених као isolated (по подразумевању), може се читати и писати својства без await. Компилер проверава границе изолације.

Како пренети податке из Actor-а спољнем коду?

Подаци из actor-а се преносе кроз async-методе које враћају Sendable типове, или кроз nonisolated методе које примају вриједности као параметре. Такође се може креирати async својство које враћа снимак стања actor-а у облику Sendable структуре.

Да ли Actor подржава насљеђивање протокола?

Да, actor може да придржава протоколима. Ако протокол садржи изоловане захтеве (actor-isolated), они аутоматски постају actor-изоловани. За асинхроне методе у протоколима, може се навести да се позивају на одређеном actor-у помоћу маркера isolated.

Резиме

  • Actor — референцни тип са аутоматском изолацијом података, представљен у Swift 5.5+
  • Изолација ради кроз извршиоца actor-а који обрађује захтеве секвенцијално
  • Спољашњи приступ actor-у захтева await — то гарантује одсуство трке
  • Nonisolated омогућава декларацију синхроних метода које немају приступ изолованом стању
  • Глобални actorи (@MainActor) проширују изолацију на целу нит извршавања
  • Reentrancy спречава deadlock-е, омогућавајући поновни улазак у actor током await

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође