Section 10/161 menit
10. `nonisolated(unsafe)` dan `@preconcurrency`
10. nonisolated(unsafe) dan @preconcurrency
nonisolated(unsafe)
Digunakan saat Anda yakin sebuah property thread-safe tapi compiler tidak bisa memverifikasinya.
swift
// ❌ Tanpa nonisolated(unsafe): error karena stored property tidak bisa nonisolated biasa
@MainActor
class AppConfiguration {
nonisolated let appName: String = "MyApp" // ✓ — konstanta, boleh nonisolated
// nonisolated var mutableSetting: String = "default" // ❌ Error di Swift 6
}
// ✓ nonisolated(unsafe): untuk mutable state dengan jaminan manual
@MainActor
class LegacyCache {
// Anda bertanggung jawab memastikan akses ke cache aman dari thread manapun
nonisolated(unsafe) var cache: NSCache<NSString, AnyObject> = .init()
// NSCache sudah thread-safe secara internal — aman dengan nonisolated(unsafe)
}
Kapan nonisolated(unsafe) Boleh Digunakan
swift
// 1. Object yang thread-safe secara internal
class SafeCounter {
nonisolated(unsafe) private var _count: Int = 0
nonisolated(unsafe) private let lock = NSLock()
var count: Int {
lock.withLock { _count }
}
func increment() {
lock.withLock { _count += 1 }
}
}
// 2. Singleton yang di-initialize sekali sebelum concurrency dimulai
class AppState {
nonisolated(unsafe) static var configuration: AppConfiguration!
static func setup() {
// Dipanggil sebelum concurrent code berjalan
configuration = AppConfiguration()
}
}
// 3. Interop dengan C/Objective-C yang thread-safe tapi tidak terbukti ke Swift type system
class CoreFoundationWrapper {
nonisolated(unsafe) let cfQueue: DispatchQueue = DispatchQueue(label: "com.app.cf")
}
@preconcurrency
Digunakan untuk adopsi bertahap — menekan warning dari tipe atau protocol yang belum di-update ke Swift Concurrency.
swift
// Suppress warning dari module lama yang belum annotate Sendable
@preconcurrency import OldFramework
// Jika protocol dari library lama tidak punya @Sendable
@preconcurrency protocol LegacyDelegate: AnyObject {
func didComplete(result: LegacyResult)
}
// Conform dengan menekan warning untuk LegacyResult yang belum Sendable
class MyDelegate: @preconcurrency LegacyDelegate {
func didComplete(result: LegacyResult) {
// Compiler tidak warning meski LegacyResult belum Sendable
}
}
@preconcurrency pada Type Declaration
swift
// Type dari SDK lama yang kita tahu aman tapi belum ada Sendable conformance
// Tambahkan di extension — jangan modif source aslinya
extension OldFrameworkObject: @unchecked Sendable {}
// Atau gunakan @preconcurrency untuk suppress warning sementara
@preconcurrency
class BridgeToLegacy {
var legacyObject: OldFrameworkObject // Tidak warning meski tidak Sendable
}