Section 15/171 menit

15. Kapan Tidak Digunakan

15. Kapan Tidak Digunakan

❌ Actor untuk Data Stateless

Kalau "actor" kamu tidak punya state mutable, gunakan struct atau function. Actor punya overhead executor; tidak ada gunanya tanpa state.

swift
// ❌ Overkill
actor URLBuilder {
    func build(_ host: String, _ path: String) -> URL { /* ... */ }
}

// ✓
enum URLBuilder {
    static func build(_ host: String, _ path: String) -> URL { /* ... */ }
}

❌ MainActor untuk Pure Computation

Computation berat (parsing, image processing, encryption) jangan di-@MainActor. UI akan freeze.

swift
// ❌
@MainActor
final class Parser {
    func parseAllRecords(_ data: Data) -> [Record] { /* CPU-heavy */ }
}

// ✓ — non-isolated atau di actor lain
final class Parser: Sendable {
    func parseAllRecords(_ data: Data) -> [Record] { /* CPU-heavy */ }
}

@unchecked Sendable Tanpa Synchronization

Pernyataan ke compiler "saya tahu yang saya lakukan". Kalau tidak ada lock/atomic/immutable di dalamnya, kamu tidak tahu yang kamu lakukan.

❌ Custom Executor untuk "Performance"

Default executor sudah sangat dioptimalkan. Ganti hanya kalau punya alasan spesifik (integrasi dengan API legacy, hardware queue). Custom executor sering memperburuk performa karena meng-bypass work-stealing.

❌ Actor untuk Singleton "Karena Sekalian"

Singleton yang read-only setelah init lebih baik jadi let global di-Sendable. Actor menambah hop untuk akses yang sebenarnya sync-safe.

❌ MainActor.run di Setiap Closure UIKit

Kalau closure dipanggil oleh UIKit dari main thread, gunakan MainActor.assumeIsolatedMainActor.run selalu hop.

swift
// ❌ Hop yang tidak perlu
button.addAction(UIAction { _ in
    Task { await MainActor.run { self.handle() } }  // hop walau sudah di main
})

// ✓
button.addAction(UIAction { _ in
    MainActor.assumeIsolated { self.handle() }  // tanpa hop
})