Section 9/201 menit

9. nonisolated(unsafe)

9. nonisolated(unsafe)

Teori: Escape Hatch dengan Tanggung Jawab

nonisolated(unsafe) adalah cara untuk menyatakan ke compiler: "percayai saya, properti ini aman diakses dari mana saja meskipun tidak ter-isolasi."

Ini adalah opt-out dari isolation checking — compiler tidak akan memperingatkan tentang concurrent access pada property ini. Programmer mengambil seluruh tanggung jawab keamanannya.

swift
// Tanpa nonisolated(unsafe): actor property hanya bisa diakses dengan await
actor Configuration {
    var timeout: Int = 30  // hanya bisa diakses dengan await
}

// Dengan nonisolated(unsafe): bisa diakses tanpa await
// Tapi compiler tidak memberikan jaminan thread-safety!
actor Configuration {
    nonisolated(unsafe) var debugMode: Bool = false
    // Kamu bertanggung jawab memastikan ini aman diakses concurrent
}

let config = Configuration()
print(config.debugMode)  // OK: tidak perlu await (tapi tidak thread-safe!)

Kapan BOLEH Digunakan (dengan Hati-hati)

swift
actor AppState {
    // KASUS 1: Nilai yang hanya ditulis sekali saat init, lalu read-only
    // (Write-once, read-many pattern)
    nonisolated(unsafe) let featureFlags: [String: Bool]

    init(flags: [String: Bool]) {
        self.featureFlags = flags  // ditulis sekali
        // Setelah ini: read-only — concurrent read aman
    }
}

// KASUS 2: Wrapping @unchecked Sendable yang sudah memiliki synchronization sendiri
actor MetricsCollector {
    nonisolated(unsafe) var hitCounter: Int32 = 0
    // Jika akses selalu via OSAtomic atau Atomic — aman secara manual

    nonisolated func recordHit() {
        // Asumsi: hanya diakses via atomic ops
        hitCounter += 1  // ⚠️ tidak atomic — ini contoh buruk!
        // Gunakan: _ = OSAtomicIncrement32(&hitCounter)
    }
}

Kapan TIDAK Boleh Digunakan

swift
// JANGAN: untuk menghindari compiler error tanpa alasan yang valid
actor UserCache {
    nonisolated(unsafe) var users: [User] = []  // ❌ BERBAHAYA

    // Ini seperti menonaktifkan airbag karena mengganggu
    // Concurrent mutation users[] → data corruption, crash
}

// Solusi yang benar:
actor UserCache {
    var users: [User] = []  // protected by actor
}

Aturan praktis: Jika kamu tidak bisa menjelaskan dengan tepat mengapa concurrent access ke property ini aman, jangan gunakan nonisolated(unsafe).