Section 5/161 menit
5. Parameter Modifier `sending`
5. Parameter Modifier sending
sending adalah modifier parameter yang menyatakan: "nilai ini dipindahkan ke isolation domain yang berbeda, pengirim tidak boleh mengakses nilai ini setelah pemanggilan."
Sintaks dan Semantik
swift
// Tanpa sending: non-Sendable tidak bisa dikirim ke async context berbeda
func process(_ value: NonSendableType) async { /* ... */ }
// Dengan sending: kompiler memverifikasi pengiriman aman
func process(_ value: sending NonSendableType) async {
// Nilai diterima di sini — bisa digunakan bebas
_ = value
}
// Pemanggil: setelah `process()`, tidak boleh akses value lagi
func caller() async {
let obj = NonSendableType()
await process(obj)
// _ = obj // ❌ Compiler error: obj sudah "dikirim"
}
sending pada Return Value
swift
// Kembalikan nilai yang berpindah dari isolation domain ke caller
actor DataStore {
private var cache: Cache = Cache() // Non-Sendable
// Caller menerima ownership — DataStore tidak simpan lagi
func extractCache() -> sending Cache {
let result = cache
cache = Cache() // Ganti dengan instance baru
return result // Kirim ownership ke caller
}
}
func processCachedData() async {
let store = DataStore()
let cache = await store.extractCache()
// cache sekarang di-own oleh context ini — aman digunakan
_ = cache.contents
}
sending dalam Closure Parameter
swift
// Fungsi yang menerima closure yang akan dijalankan di isolation domain berbeda
func runOnBackground<T: Sendable>(
_ work: sending @Sendable () async -> T
) async -> T {
await Task.detached { await work() }.value
}
// Non-Sendable yang di-capture harus "dikirim" bersama closure
class WorkItem { // Non-Sendable
var progress: Double = 0
}
func scheduleWork() async {
let item = WorkItem()
// item di-capture oleh closure yang di-send ke background
// Setelah ini, item tidak boleh diakses di scope ini
await runOnBackground { [item] in
item.progress = 1.0
return item.progress
}
}