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 } }
}
}