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)