Sendable, iş parçacıkları arasında aktarım için güvenli türleri işaretleyen bir Swift protokolüdür. Eşzamanlılıkla (actor, async/await, Task) çalışırken Swift derleyicisi, yalıtılmış bağlamlar arasında aktarılan tüm verilerin Sendable ile uyumlu olmasını gerektirir. Bu, veri yarışlarına yol açabilecek güvenli olmayan türlerin yanlışlıkla aktarılmasını önler. Protokol bir sözleşme görevi görür: Sendable ile uyumlu bir tür, dahili senkronize edilmemiş durumun olmadığını garanti eder. WWDC 2021'e göre, Sendable protokolü güvenli çoklu iş parçacıklı bir mimari tasarlarken zorunlu bir unsurdur.
Önemli Noktalar
Sendable, Swift standart kütüphanesinden (SE-0302) yalıtım alanları arasında aktarım için güvenli türleri işaretleyen bir protokoldür. Yalıtım alanı, bir actor, Task görevi veya @MainActor bağlamı anlamına gelir. Sendable herhangi bir gereksinim içermez — bir güvenlik işaretçisi olarak işlev görür.
Swift 5.5'ten önce, geliştiriciler DispatchQueue aracılığıyla herhangi bir nesneyi iş parçacıkları arasında aktarabilirdi ve derleyici bunun güvenli olup olmadığını kontrol etmezdi. Sendable bu boşluğu kapatır: artık derleyicinin kendisi iş parçacıkları arası aktarımları izler ve güvensiz olanları engeller. Bu, eşzamanlı kodu çalıştırmadan önce daha güvenilir hale getirir.
struct UserProfile: Sendable {
let name: String
let age: Int
}
class NonSendableClass {
var counter: Int = 0
}
Örnekte, UserProfile, Sendable türlerinin sabit özelliklerine sahip bir struct olduğu için iş parçacıkları arasında güvenle aktarılabilir. NonSendableClass, await aracılığıyla veya bir Task'e aktarılmaya çalışıldığında derleme hatasına neden olur.
Swift'teki Sendable türleri üç kategoriye ayrılır: Sendable özelliklere sahip değer türleri, değişmez duruma sahip final sınıfları ve @Sendable ile işaretlenmiş fonksiyonlar/closure'lar. Derleyici, değer türleri için otomatik olarak Sendable uyumluluğunu çıkarır.
Struct, Enum ve tuple, tüm özellikleri ve ilişkili değerleri de Sendable ise otomatik olarak Sendable olur. Bu muhafazakâr bir yaklaşımdır: en az bir özellik Sendable ile uyumlu değilse, tüm tür güvenli olarak tanınmaz.
| Tür | Sendable | Koşul |
|---|---|---|
| Struct | Evet (açık bildirim olmadan) | Tüm özellikler Sendable |
| Enum | Evet (açık bildirim olmadan) | Tüm ilişkili değerler Sendable |
| Final class | Evet (açık bildirimle) | Tüm let özellikleri Sendable, var yok |
| Non-final class | Hayır | Kalıtım nedeniyle Sendable olamaz |
Tüm Swift yerleşik türleri — Int, String, Double, Bool, Optional, Array, Dictionary, Set — Sendable ile uyumludur. Bu, tür kompozisyonunu varsayılan olarak güvenli kılar. Geliştiricinin yalnızca özel sınıflara dikkat etmesi gerekir.
@unchecked Sendable, bir sınıfın derleyici kontrollerini atlayarak kendisini açıkça Sendable olarak bildirmesine izin veren bir mekanizmadır. Geliştirici, böyle bir sınıfın iş parçacığı güvenliğinin sorumluluğunu üstlenir. Bu, Objective-C köprüleri ve optimize edilmiş yapılar için kullanışlıdır.
@unchecked Sendable, bir sınıfın dahili olarak kilitler veya atomik işlemler aracılığıyla güvenliği sağlaması ancak derleyicinin bunu statik olarak doğrulayamaması durumunda kullanılır. Örneğin, os_unfair_lock veya pthread_mutex_t içeren bir sınıf — iş parçacığı güvenliği kod tarafından sağlanır, ancak Swift bunu görmez.
final class AtomicCounter: @unchecked Sendable {
private var value: Int = 0
private let lock = NSLock()
func increment() {
lock.lock()
value += 1
lock.unlock()
}
}
@unchecked Sendable kullanımı dikkatli yapılmalıdır. Diğer geliştiricilere açık bir sinyaldir: "Kontrol ettim, bu güvenli." Uygulama hatası, bulunması zor yarışlara yol açabilir. @unchecked kullanmadan önce, türün gerçekten bir değer türü olarak yeniden yazılamayacağından emin olun.
Actor ve Sendable aynı madalyonun iki yüzüdür. Actor durumunu yalıtır, ancak dış dünyayla veri alışverişi yapmak için Sendable türler döndürmelidir. Bir actor yöntemi Sendable olmayan bir tür döndürürse, derleyici bir uyarı veya hata verir.
Bir actor harici koda veri gönderdiğinde, bu veri yalıtım sınırını geçer. Sendable, alıcının bunu actor dışında güvenle kullanabileceğini garanti eder. Actor'ün kendisi yalıtılmış kalır — iç durumu açığa çıkmaz.
struct AccountSnapshot: Sendable {
let id: UUID
let balance: Double
let lastUpdated: Date
}
actor BankActor {
private var balance: Double = 0
func snapshot() async -> AccountSnapshot {
return AccountSnapshot(
id: UUID(),
balance: balance,
lastUpdated: Date()
)
}
}
AccountSnapshot, yalnızca Sendable türlerinin let özelliklerini içeren bir Sendable struct'tır. Bu yaklaşım, bir actor'den veri çıkarmak için en iyi uygulamadır. Durum anlık görüntüsü değer olarak aktarılır ve actor durumu üzerindeki kontrolünü kaybetmez.
@Sendable, closure'ın Sendable olmayan verileri değiştirilebilir biçimde yakalamamasını garanti eden fonksiyonlar ve closure'lar için bir özniteliktir. Bir closure, Task'e veya actor yöntemine aktarıldığında Sendable olmalıdır.
Derleyici, @Sendable closure'ın sınıflara değiştirilebilir referanslar yakalamadığını kontrol eder. Sendable türlerinin let özelliklerini yakalamaya izin verilir. Referans türündeki bir var değişkenini yakalamak, closure mutasyonla eşzamanlı olarak yürütülebileceği için hataya neden olur.
func performAsync(operation: @Sendable () -> Void) {
Task {
await operation()
}
}
let constant = "Safe"
var counter = 0
// counter — var yakalamak counter'ı değiştirir, derleme hatası
performAsync { // ❌ Yakalanan değişkenin mutasyonu
print(constant)
}
Kural basittir: bir @Sendable closure yalnızca kendisi Sendable olan ve dışarıdan değiştirilmeyecek verileri yakalayabilir. Sınıflar için, sınıf Sendable olarak işaretlenmemişse zayıf referans weak self yakalamaya izin verilir. Bu, klasik retain döngülerini ve yarış koşullarını önler.
Sıkça Sorulan Sorular
Sendable, derleyiciye "bu tür iş parçacıkları arasında güvenle aktarılabilir" diyen bir işaretçidir. Struct'lar ve sabitler genellikle varsayılan olarak Sendable'dır, sınıflar açıkça belirtilmediği sürece değildir.
Sendable özelliklere sahip değer türleri (struct, enum), değişmez duruma sahip final sınıfları ve tüm temel Swift türleri: Int, String, Double, Bool, Array, Dictionary, Optional — otomatik olarak Sendable ile uyumludur.
@unchecked Sendable, derleyicinin statik kontrolü olmadan bir sınıfı Sendable olarak bildirmenin bir yoludur. Geliştirici, genellikle kilitler veya atomik işlemler aracılığıyla güvenliği kendisi sağlar.
Actor durumunu yalıtır, ancak harici koda veri döndürürken bu veri yalıtım sınırını geçer. Sendable, alıcının bu verileri actor dışında kullanırken yarışlarla karşılaşmayacağını garanti eder.
Tüm özellikleri Sendable türlerinin sabitleri olan bir final sınıfına Sendable protokolünü ekleyin. Sınıf kilit kullanıyorsa @unchecked Sendable kullanılabilir, ancak bu dikkat gerektirir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun