Actor — apa itu, isolasi data dan konkurensi

Penulis: IT Sectr Diterbitkan: 2026-06-18 Waktu membaca: 11 mnt

Actor — adalah tipe yang diperkenalkan di Swift 5.5+ yang memecahkan masalah race condition data pada tingkat bahasa. Berbeda dengan kunci manual dan antrian DispatchQueue, actor secara otomatis mengisolasi keadaannya dan menyinkronkan akses ke sana. Ini berarti dua thread tidak dapat secara bersamaan mengubah properti yang sama dari tipe actor, yang menghilangkan race condition tanpa upaya tambahan dari pengembang. Mekanismenya didasarkan pada konsep isolasi actor, di mana kompiler melacak akses ke properti dan metode actor. Menurut Apple, 2025, model actor adalah bagian fundamental dari sistem konkurensi Swift.

Poin Utama

  • Actor — tipe yang secara otomatis mengisolasi keadaannya dari race condition pada tingkat kompiler
  • Isolasi menjamin bahwa hanya satu thread yang secara bersamaan mengakses instance actor
  • Panggilan metode actor dijalankan secara asinkron melalui mekanisme async/await
  • Nonisolated memungkinkan penonaktifan isolasi secara selektif untuk anggota actor tertentu
  • Reentrancy memungkinkan masuk kembali ke actor, mencegah saling blokir

Apa itu Actor di Swift?

Actor — adalah tipe referensi, mirip dengan kelas, tetapi dengan perlindungan otomatis terhadap race condition. Ini diperkenalkan di Swift 5.5 sebagai bagian dari sistem konkurensi bersama dengan async/await dan Task. Actor menjamin bahwa keadaannya yang dapat berubah tidak akan pernah dibaca atau ditulis secara bersamaan dari thread yang berbeda tanpa sinkronisasi eksplisit.

Sintaks deklarasi Actor

Untuk mendeklarasikan actor, gunakan kata kunci actor, diikuti oleh kurung kurawal dengan anggotanya. Secara sintaksis, actor mirip dengan kelas, tetapi perilakunya sangat berbeda.

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

Kompiler secara otomatis mengisolasi semua properti dan metode actor sehingga hanya dapat diakses di dalam konteks actor. Mencoba mengakses balance dari luar actor akan menghasilkan kesalahan kompiler jika panggilan tidak ditandai sebagai async.

Bagaimana isolasi data bekerja di Actor

Isolasi data — adalah konsep kunci dari actor. Actor menjamin akses saling eksklusif ke keadaannya melalui mekanisme eksekutor actor (actor executor). Setiap actor memiliki eksekutornya sendiri yang memproses semua akses ke anggota yang diisolasi secara sekuensial.

Prinsip kerja isolasi

Ketika kode di luar actor memanggil metodenya, panggilan ditempatkan dalam antrian eksekutor actor. Actor hanya menjalankan satu tugas pada satu waktu, yang menjamin tidak adanya race condition. Jika dua thread secara bersamaan memanggil deposit, panggilan kedua menunggu yang pertama selesai.

swift
let account = BankAccount(initialBalance: 1000.0)
// Panggilan asinkron — diperlukan dari luar actor
await account.deposit(amount: 500.0)
let currentBalance = await account.getBalance()

Setiap panggilan metode actor memerlukan await, karena actor mungkin sedang sibuk dengan tugas lain. Ini bukan bug, tetapi desain sadar yang mencegah race condition. Swift secara implisit membuat getter dan setter properti actor menjadi async, sehingga membaca properti juga memerlukan await.

Perbedaan utama antara Actor dan kelas

Actor dan kelas adalah tipe referensi, tetapi perilaku mereka di lingkungan multi-threaded sangat berbeda. Kelas tidak memberikan perlindungan otomatis terhadap race condition, sementara actor membangunnya di tingkat kompiler melalui sistem tipe.

KarakteristikActorClass
Perlindungan raceOtomatis, di tingkat kompilerMemerlukan sinkronisasi manual
Akses ke propertiHanya melalui await dari luarLangsung, tanpa sinkronisasi
PewarisanHanya dari actor lainPewarisan kelas standar
Kesesuaian protokolDapat mematuhi protokolStandar
KinerjaOverhead rendah saat isolasiTanpa sinkronisasi — lebih cepat

Pewarisan Actor

Actor hanya dapat mewarisi dari actor lain dan tidak dapat mewarisi dari kelas. Ini dilakukan secara sadar, karena kelas tidak memiliki mekanisme isolasi actor, dan mencampur dua model akan menyebabkan perilaku tidak terdefinisi.

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

Panggilan asinkron metode Actor

Panggilan asinkron — adalah mekanisme interaksi dengan actor dari kode eksternal. Karena actor mengisolasi keadaannya, setiap akses ke anggotanya dari luar memerlukan await. Ini memungkinkan Swift menjamin bahwa kode pemanggil tidak memblokir thread dan actor dapat memproses permintaan lain.

Actor global dan lokal

Selain tipe actor yang dideklarasikan, Swift mendukung actor global — atribut @MainActor, yang menandai kelas, properti, atau metode sebagai dijalankan di thread utama. Ini sangat berguna saat bekerja dengan UIKit dan SwiftUI.

swift
@MainActor
class ViewModel: ObservableObject {
    @Published var title: String = ""
    
    func updateTitle() {
        // Kode ini dijamin berjalan di thread utama
        title = "New Title"
    }
}

Penggunaan @MainActor menghilangkan kebutuhan untuk memanggil DispatchQueue.main.async secara manual, yang membuat kode lebih bersih dan aman. Kompiler memeriksa bahwa perpindahan ke thread utama terjadi dengan benar.

Konteks Nonisolated dan actor-isolated

Nonisolated — adalah kata kunci yang memungkinkan menandai metode atau properti terhitung dari actor sebagai tidak terisolasi. Anggota tersebut tidak memiliki akses ke keadaan terisolasi actor, tetapi dapat dipanggil tanpa await dari luar actor.

Fungsi Nonisolated

Metode nonisolated berguna untuk perhitungan yang tidak bergantung pada keadaan actor yang dapat berubah. Misalnya, metode formatBalance tidak mengakses balance secara langsung, hanya memformat nilai yang dilewatkan — metode seperti itu dapat dengan aman dibuat nonisolated.

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

Anggota nonisolated dijalankan secara sinkron dan tidak memerlukan await. Namun, mereka tidak dapat langsung membaca properti terisolasi actor. Jika metode nonisolated memerlukan nilai dari actor, itu harus dilewatkan sebagai parameter.

Reentrancy dan masuk kembali

Reentrancy — adalah mekanisme yang memungkinkan masuk kembali ke actor selama menunggu panggilan asinkron. Tanpa reentrancy, actor dapat selamanya terblokir jika satu metodenya menunggu metode lain, yang pada gilirannya menunggu yang pertama.

Bagaimana reentrancy bekerja

Ketika kode di dalam actor menjalankan await, actor menangguhkan tugas saat ini dan dapat memproses tugas lain yang ditempatkan dalam antrian. Setelah await selesai, tugas dilanjutkan. Ini mencegah deadlock, tetapi memerlukan kehati-hatian: keadaan actor di antara titik await dapat berubah.

swift
actor DataProcessor {
    var cache: [Int: String] = [:]
    
    func process(id: Int) async -> String {
        if let cached = cache[id] {
            return cached
        }
        // await — titik masuk kembali
        let result = await fetchData(id: id)
        // Cache mungkin berubah setelah await — periksa lagi
        cache[id] = result
        return result
    }
}

Pengembang harus mempertimbangkan reentrancy dan memeriksa keadaan actor setelah titik await. Kesalahan umum adalah asumsi bahwa isolasi actor dipertahankan melalui jeda asinkron. Dalam praktiknya, antara await dan instruksi berikutnya, keadaan dapat berbeda dari yang diharapkan.

Pertanyaan yang Sering Diajukan

Apa perbedaan Actor dengan kelas di Swift?

Actor secara otomatis mengisolasi keadaannya dari race condition, memerlukan await untuk akses dari luar. Kelas tidak memberikan perlindungan seperti itu — pengembang sendiri yang bertanggung jawab atas sinkronisasi melalui kunci atau antrian. Actor hanya mewarisi dari actor, kelas dari kelas.

Bisakah mewarisi dari Actor?

Ya, actor dapat mewarisi dari actor lain. Subkelas menerima semua properti dan metode terisolasi dari induk. Actor tidak dapat mewarisi dari kelas, karena kelas tidak memiliki mekanisme isolasi actor di tingkat kompiler.

Apa itu konteks actor-isolated?

Konteks actor-isolated — adalah area kode di mana akses langsung ke keadaan actor yang dapat berubah diizinkan. Di dalam metode actor yang ditandai sebagai isolated (default), properti dapat dibaca dan ditulis tanpa await. Kompiler memeriksa batas isolasi.

Bagaimana mentransfer data dari Actor ke kode eksternal?

Data dari actor ditransfer melalui metode async yang mengembalikan tipe Sendable, atau melalui metode nonisolated yang menerima nilai sebagai parameter. Juga dapat membuat properti async yang mengembalikan snapshot keadaan actor dalam bentuk struktur Sendable.

Apakah Actor mendukung pewarisan protokol?

Ya, actor dapat mematuhi protokol. Jika protokol berisi persyaratan terisolasi (actor-isolated), mereka secara otomatis menjadi actor-terisolasi. Untuk metode asinkron dalam protokol, dapat ditentukan dengan marker isolated bahwa mereka harus dipanggil pada actor tertentu.

Kesimpulan

  • Actor — tipe referensi dengan isolasi data otomatis, diperkenalkan di Swift 5.5+
  • Isolasi bekerja melalui eksekutor actor yang memproses permintaan secara sekuensial
  • Akses eksternal ke actor memerlukan await — ini menjamin tidak adanya race condition
  • Nonisolated memungkinkan mendeklarasikan metode sinkron yang tidak memiliki akses ke keadaan terisolasi
  • Actor global (@MainActor) menyebarkan isolasi ke seluruh thread eksekusi
  • Reentrancy mencegah deadlock dengan mengizinkan masuk kembali ke actor selama await

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga