3. nonisolated dan isolated Parameter
3. nonisolated dan isolated Parameter
3.1 Teori: Biaya Isolation
Setiap akses ke isolated property atau method membutuhkan actor hop — sebuah context switch ke executor actor. Ini memang lebih efisien dari thread switch konvensional (karena cooperative), tapi tetap ada overhead: bookkeeping, queue operation, dan potential task suspension.
Untuk data yang tidak memerlukan perlindungan (misalnya immutable constants atau computed properties murni), overhead ini tidak diperlukan. nonisolated adalah cara untuk menyatakan: "bagian ini aman diakses langsung, tanpa perlu melalui antrian actor."
3.2 nonisolated — Opt-Out dari Isolation
nonisolated memungkinkan method/property diakses tanpa await dari mana saja, tapi sebagai konsekuensi tidak boleh mengakses isolated state actor:
actor UserProfile {
var name: String // isolated — bisa berubah, butuh perlindungan
var email: String // isolated — sama
let id: UUID // immutable — tidak bisa berubah, tidak butuh perlindungan
init(name: String, email: String) {
self.name = name
self.email = email
self.id = UUID()
}
// Bisa dipanggil tanpa await dari mana saja
// Tidak ada overhead actor hop — langsung eksekusi
nonisolated func displayID() -> String {
return id.uuidString // OK: id adalah let (immutable)
}
// ❌ ERROR: name adalah var — bisa berubah, tidak aman tanpa isolation
// nonisolated func displayName() -> String { name }
}
// Penggunaan:
let profile = UserProfile(name: "Ari", email: "ari@example.com")
let idString = profile.displayID() // synchronous! tidak perlu await
Kapan gunakan nonisolated:
- Method hanya mengakses
letproperty (immutable) - Method hanya mengakses property lain yang juga
nonisolated - Pure functions / computed properties tanpa mutable state
- Protocol conformances yang harus synchronous (misalnya
CustomStringConvertible)
Kapan TIDAK gunakan nonisolated:
- Jika method mengakses
varproperty — compiler akan error - Jika method memanggil isolated method lain — butuh await
- Jika ada keraguan — biarkan actor melindunginya
actor Logger {
private var logs: [String] = []
private let prefix: String // immutable
// nonisolated OK: hanya akses let
nonisolated var description: String {
"Logger[\(prefix)]" // CustomStringConvertible tanpa await
}
// Harus isolated: mutasi logs
func log(_ message: String) {
logs.append("[\(prefix)] \(message)")
}
// nonisolated OK karena hanya akses let + pure computation
nonisolated func format(_ message: String) -> String {
"[\(prefix)] \(message)"
}
}
3.3 isolated Parameter — Utility Function dalam Domain Actor
isolated parameter memungkinkan fungsi bebas (bukan method actor) untuk berjalan di dalam isolation domain actor tertentu:
actor Database {
var records: [String: String] = [:]
}
// Fungsi ini bukan method Database, tapi berjalan DALAM isolation domain 'db'
// Artinya: tidak butuh await untuk akses db.records
func insertRecord(key: String, value: String, into db: isolated Database) {
db.records[key] = value // OK: kita sedang dalam isolation domain db
}
// Penggunaan — butuh await karena harus hop ke Database executor
let db = Database()
Task {
await insertRecord(key: "user_1", value: "Ari", into: db)
}
Mengapa ini berguna? Bayangkan kamu punya banyak utility functions yang logikanya terkait erat dengan sebuah actor, tapi tidak ingin membuat actor membengkak dengan banyak method. isolated parameter memisahkan concerns sambil tetap mendapat keamanan isolation.
Perbandingan pendekatan:
// Pendekatan 1: method di dalam actor (meningkatkan ukuran actor)
actor DataProcessor {
var data: [Int] = []
func filterEven() { data = data.filter { $0.isMultiple(of: 2) } }
func filterOdd() { data = data.filter { !$0.isMultiple(of: 2) } }
func sort() { data.sort() }
// ... actor bisa jadi sangat besar
}
// Pendekatan 2: isolated parameter (actor tetap kecil, logic di luar)
actor DataProcessor {
var data: [Int] = []
}
func filterEven(processor: isolated DataProcessor) {
processor.data = processor.data.filter { $0.isMultiple(of: 2) }
}
func sort(processor: isolated DataProcessor) {
processor.data.sort()
}
Kapan gunakan isolated parameter:
- Utility functions yang logikanya terkait satu actor tapi bukan bagian inti actor
- Extension functions yang perlu akses isolated state
- Testing helpers yang perlu inspect/modify actor state
Kapan TIDAK gunakan isolated parameter:
- Jika function butuh akses ke dua actor berbeda — tidak bisa punya dua
isolatedparameter dari actor berbeda sekaligus (deadlock potential) - Jika logic memang bagian inti dari actor — jadikan method biasa saja