Section 18/201 menit

18. nonisolated on init

18. nonisolated on init

Teori: Fleksibilitas Inisialisasi

Sebelum Swift 6.2, init dari @MainActor class atau actor selalu diisolasi ke actor/MainActor tersebut. Ini menyebabkan semua caller harus await:

swift
// Swift 6.0: init adalah @MainActor — semua caller harus await
@MainActor
class ViewModel {
    var data: [Item] = []

    init() {  // implicitly @MainActor
        // setup
    }
}

// Caller:
Task {
    let vm = await ViewModel()  // harus await meski init trivial!
}

Swift 6.2 memungkinkan nonisolated init — init yang bisa dipanggil dari context mana saja tanpa await:

swift
// Swift 6.2: nonisolated init
@MainActor
class ViewModel {
    var data: [Item] = []
    private let config: Configuration

    // Init tidak butuh @MainActor — hanya set constant properties
    nonisolated init(config: Configuration) {
        self.config = config
        // Tidak boleh akses @MainActor properties di sini
        // self.data = []  // ❌ ERROR: data adalah @MainActor
    }
}

// Caller — tidak perlu await:
let vm = ViewModel(config: .default)  // synchronous!
// vm sudah bisa digunakan, tapi akses property harus tetap await
await vm.loadInitialData()

Aturan nonisolated init

swift
@MainActor
class Example {
    let constant: String
    var mutableState: [Int] = []

    nonisolated init(constant: String) {
        self.constant = constant  // ✅ set let property — OK
        // self.mutableState = [1,2,3]  // ❌ mutableState adalah @MainActor
    }
}

actor MyActor {
    nonisolated let id: UUID
    var data: [String] = []

    nonisolated init() {
        self.id = UUID()  // ✅ nonisolated let — OK
        // self.data = ["initial"]  // ❌ data adalah actor-isolated
    }
}

Kapan Menggunakan

Gunakan nonisolated init ketika:

  • Init hanya men-setup immutable (let) properties
  • Ingin membuat object tanpa butuh async context
  • Dependency injection di synchronous context (AppDelegate, SceneDelegate setup)

Jangan gunakan ketika:

  • Init perlu setup mutable state — harus dalam isolation
  • Init melakukan async work (gunakan factory method async sebagai gantinya)

PENUTUP