Section 7/161 menit

7. Protocol Conformance dan Isolation

7. Protocol Conformance dan Isolation

Saat tipe yang ter-isolate conform ke protocol, ada aturan khusus yang harus dipahami.

Protocol Requirements dan Isolation

swift
protocol DataSource {
    func fetchData() async -> [String]
}

// Class @MainActor conform ke protocol
@MainActor
class UIDataSource: DataSource {
    var cache: [String] = []

    // Method ini implisit @MainActor (class di @MainActor)
    func fetchData() async -> [String] {
        return cache  // ✓ — akses @MainActor state
    }
}

// Penggunaan via protocol type — isolation HILANG
func useDataSource(_ source: any DataSource) async {
    let data = await source.fetchData()
    // source.fetchData() dipanggil tanpa @MainActor guarantee
    // Caller tidak tahu implementasinya di @MainActor
}

Explicit Isolation dalam Protocol

swift
// Protocol yang mensyaratkan @MainActor
@MainActor
protocol MainActorDataSource {
    func fetchData() -> [String]  // Tidak perlu async — sudah di @MainActor
}

// Atau protokol dengan async yang secara implisit bisa di-hop
protocol AsyncDataProvider {
    @MainActor func updateUI(with data: [String])  // Method spesifik @MainActor
    func fetchBackground() async -> [String]       // Method nonisolated
}

Isolation dan Existential Types

swift
// Masalah: existential type menghilangkan isolation info
protocol Processor {
    func process() async
}

@MainActor
class MainProcessor: Processor {
    func process() async {
        // Ini berjalan di @MainActor
    }
}

// any Processor — compiler tidak tahu isolation implementasinya
let processor: any Processor = MainProcessor()
await processor.process()  // Hop ke mana? Compiler tidak tahu — nonisolated

// Solusi: gunakan generics untuk mempertahankan isolation info
func run<P: Processor>(_ processor: P) async {
    await processor.process()  // Compiler tahu tipe concrete dan isolationnya
}

Retroactive Conformance dan Isolation

swift
// Hati-hati saat menambah conformance ke tipe yang sudah ada
extension URLSession: @unchecked Sendable {}  // URLSession sudah Sendable
// @unchecked: Anda yang bertanggung jawab memastikan thread safety

// Untuk tipe milik sendiri, gunakan conformance yang tepat
class NetworkManager: @unchecked Sendable {
    // @unchecked: kita jamin thread safety via internal lock
    private let lock = NSLock()
    private var _config: Config = .default

    var config: Config {
        get { lock.withLock { _config } }
        set { lock.withLock { _config = newValue } }
    }
}