Section 2/171 menit
2. Masalah yang Dipecahkan
2. Masalah yang Dipecahkan
Masalah: Kode Async yang "Bekerja" tapi Tidak Aman
Sebelum Swift Concurrency, kita menulis kode async dengan completion handler + DispatchQueue. Kode "bekerja" di test tapi punya race condition yang muncul di production tanpa peringatan.
swift
// ❌ TANPA isolation: race condition senyap
final class ImageCache {
private var storage: [URL: UIImage] = [:]
func image(for url: URL, completion: @escaping (UIImage?) -> Void) {
if let cached = storage[url] {
completion(cached)
return
}
URLSession.shared.dataTask(with: url) { data, _, _ in
let image = data.flatMap(UIImage.init)
if let image {
self.storage[url] = image // ❌ Race: dipanggil dari banyak thread
}
completion(image)
}.resume()
}
}
Dengan Swift Concurrency + isolation, masalah ini menjadi compile error, bukan crash production.
swift
// ✓ DENGAN isolation: race ter-deteksi compiler
actor ImageCache {
private var storage: [URL: UIImage] = [:]
func image(for url: URL) async throws -> UIImage? {
if let cached = storage[url] { return cached }
let (data, _) = try await URLSession.shared.data(from: url)
let image = UIImage(data: data)
if let image { storage[url] = image }
return image
}
}
Masalah: Tidak Ada Konsistensi di Tim
Tanpa best practice yang disepakati tim:
- Satu engineer pakai
@MainActoreverywhere → UI lag. - Satu engineer pakai actor untuk semua → over-engineering, banyak hop.
- Satu engineer pakai
@unchecked Sendabletanpa lock → data race senyap.
Materi ini menetapkan default kollektif yang masuk akal untuk tim.