Section 11/161 menit

11. Isolation Inference Rules

11. Isolation Inference Rules

Swift compiler menggunakan aturan inferensi untuk menentukan isolation sebuah deklarasi saat tidak disebutkan eksplisit.

Aturan Inferensi untuk Stored Properties

swift
@MainActor
struct Config {
    var name: String  // Implisit @MainActor — ikut struct
}

// Actor stored properties: ikut aktor
actor Cache {
    var data: [String: Any] = [:]  // Implisit actor-isolated
}

// Nonisolated tidak bisa untuk var — hanya let
struct SharedData {
    nonisolated let id: UUID  // ✓ — konstanta
    // nonisolated var mutable: Int  // ❌ — var tidak boleh nonisolated di isolated type
}

Aturan Inferensi untuk Methods

swift
@MainActor
class ViewModel {
    var data: [String] = []

    func update() {           // Implisit @MainActor — ikut class
        data.append("new")
    }

    nonisolated func describe() -> String {  // Eksplisit nonisolated — override
        return "ViewModel"                    // Tidak bisa akses data (di @MainActor)
    }

    nonisolated func staticInfo() -> String {  // ✓ Hanya akses nonisolated state
        return Bundle.main.bundleIdentifier ?? "unknown"
    }
}

Inferensi dari Protocol Conformance

swift
// Protocol menentukan isolation requirements
@MainActor
protocol ViewModelProtocol {
    var title: String { get }
    func refresh() async
}

// Conformance implisit mewarisi isolation dari protocol
class ConcreteViewModel: ViewModelProtocol {
    var title: String = ""  // Implisit @MainActor karena protocol @MainActor

    func refresh() async {  // Implisit @MainActor karena protocol requirement
        title = "Refreshed"
    }
}

// Tapi bisa override dengan isolation lebih ketat atau sama
class ActorViewModel: @MainActor ViewModelProtocol {
    var title: String = ""
    func refresh() async {}
}

Inferensi untuk Closures

swift
@MainActor
class Controller {
    func example() {
        // Closure di method @MainActor → implisit @MainActor
        let closure1 = { [self] in
            _ = self  // ✓ — implisit @MainActor
        }

        // Closure dengan tipe @Sendable → nonisolated (override inferensi)
        let closure2: @Sendable () -> Void = {
            // Tidak bisa akses self — nonisolated
        }

        // Closure async → mewarisi isolation dari enclosing
        let closure3: () async -> Void = {
            // Implisit @MainActor
        }
    }
}