Sendable — bu Swift protokoli bo‘lib, iplar o‘rtasida uzatish uchun xavfsiz bo‘lgan turlarni belgilaydi. Konkurentlik bilan (actor, async/await, Task) ishlaganda, Swift kompilyatori izolyatsiyalangan kontekstlar o‘rtasida uzatiladigan barcha ma’lumotlar Sendable-ga mos kelishini talab qiladi. Bu ma’lumotlar poygasiga olib kelishi mumkin bo‘lgan xavfli turlarning tasodifiy uzatilishini istisno qiladi. Protokol shartnoma vazifasini bajaradi: Sendable-ga mos keladigan tur ichki sinxronlashtirilmagan holatning yo‘qligini kafolatlaydi. WWDC 2021 ma’lumotlariga ko‘ra, Sendable protokoli xavfsiz ko‘p ipli arxitekturani loyihalashda majburiy element hisoblanadi.
Asosiy
Sendable — bu Swift standart kutubxonasidan (SE-0302) olingan protokol bo‘lib, izolyatsiya domenlari o‘rtasida uzatish uchun xavfsiz turlarni belgilaydi. Izolyatsiya domeni deganda actor, Task vazifasi yoki @MainActor konteksti tushuniladi. Sendable hech qanday talablarni o‘z ichiga olmaydi — u xavfsizlik markeri vazifasini bajaradi.
Swift 5.5 dan oldin dasturchilar DispatchQueue orqali iplar o‘rtasida istalgan ob’ektni uzata olishgan va kompilyator bu xavfsizmi yoki yo‘qmi tekshirmagan. Sendable bu bo‘shliqni yopadi: endi kompilyator o‘zi iplararo uzatishlarni kuzatadi va xavflilarini bloklaydi. Bu konkurent kodni ishga tushirishdan oldin ham ishonchliroq qiladi.
struct UserProfile: Sendable {
let name: String
let age: Int
}
class NonSendableClass {
var counter: Int = 0
}
Misolda UserProfile iplar o‘rtasida xavfsiz uzatilishi mumkin, chunki bu Sendable turlarining doimiy xususiyatlariga ega struktura. NonSendableClass await yoki Task orqali uzatishga urinishda kompilyatsiya xatosiga sabab bo‘ladi.
Sendable turlari Swift-da uch kategoriyaga bo‘linadi: Sendable xususiyatlariga ega qiymat turlari, o‘zgaruvchan holatga ega final sinflar va @Sendable bilan belgilangan funksiyalar/yopilmalar. Kompilyator qiymat turlari uchun Sendable-ga moslikni avtomatik chiqaradi.
Struct, enum va tuple agar barcha xususiyatlari va bog‘langan qiymatlari ham Sendable bo‘lsa, avtomatik ravishda Sendable bo‘ladi. Bu konservativ yondashuv: agar hech bo‘lmasa bitta xususiyat Sendable-ga mos kelmasa, butun tur xavfsiz deb hisoblanmaydi.
| Tur | Sendable | Shart |
|---|---|---|
| Struct | Ha (aniq ko‘rsatmasdan) | Barcha xususiyatlar Sendable |
| Enum | Ha (aniq ko‘rsatmasdan) | Barcha associated values Sendable |
| Final class | Ha (aniq ko‘rsatish bilan) | Barcha let xususiyatlari Sendable, var yo‘q |
| Non-final class | Yo‘q | Meros tufayli Sendable bo‘la olmaydi |
Swift-ning barcha o‘rnatilgan turlari — Int, String, Double, Bool, Optional, Array, Dictionary, Set — Sendable-ga mos keladi. Bu turlar kompozitsiyasini standart bo‘yicha xavfsiz qiladi. Dasturchi faqat maxsus sinflarga e’tibor berishi kerak.
@unchecked Sendable — bu sinfga kompilyator tekshiruvlarini chetlab o‘tib, o‘zini Sendable deb e’lon qilishga imkon beruvchi mexanizm. Dasturchi bunday sinfning ip xavfsizligi uchun javobgarlikni o‘z zimmasiga oladi. Bu Objective-C ko‘priklari va optimallashtirilgan tuzilmalar uchun foydali.
@unchecked Sendable sinf ichki ravishda qulflar yoki atom operatsiyalar orqali xavfsizlikni ta’minlaganda qo‘llaniladi, lekin kompilyator buni statik tekshira olmaydi. Masalan, os_unfair_lock yoki pthread_mutex_t bo‘lgan sinf — uning ip xavfsizligi kod bilan ta’minlanadi, lekin Swift buni ko‘rmaydi.
final class AtomicCounter: @unchecked Sendable {
private var value: Int = 0
private let lock = NSLock()
func increment() {
lock.lock()
value += 1
lock.unlock()
}
}
@unchecked Sendable ni ehtiyotkorlik bilan ishlating. Bu boshqa dasturchilar uchun aniq signal: “Men tekshirdim, bu xavfsiz”. Amalga oshirishdagi xato qiyin aniqlanadigan poygalarga olib kelishi mumkin. @unchecked ni qo‘llashdan oldin, turning haqiqatan ham qiymat turi sifatida qayta yozilmasligiga ishonch hosil qilish kerak.
Actor va Sendable bir medalning ikki tomonidir. Actor o‘z holatini izolyatsiya qiladi, lekin tashqi dunyo bilan ma’lumot almashish uchun Sendable turlarini qaytarishi kerak. Agar actor metodi Sendable bo‘lmagan turni qaytarsa, kompilyator ogohlantirish yoki xato beradi.
Actor tashqi kodga ma’lumot yuborganda, bu ma’lumotlar izolyatsiya chegarasini kesib o‘tadi. Sendable qabul qiluvchining ulardan actor tashqarisida xavfsiz foydalanishini kafolatlaydi. Actorning o‘zi izolyatsiyalangan holda qoladi — uning ichki holati oshkor etilmaydi.
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 — bu faqat Sendable turlarining let xususiyatlariga ega Sendable struktura. Bu yondashuv actordan ma’lumot olish uchun best practice hisoblanadi. Holatning lahzali ko‘rinishi qiymat sifatida uzatiladi va actor o‘z holati ustidan nazoratni yo‘qotmaydi.
@Sendable — bu funksiyalar va yopilmalar uchun atribut bo‘lib, yopilmaning Sendable bo‘lmagan ma’lumotlarni o‘zgaruvchan shaklda tutib olmasligini kafolatlaydi. Yopilma Task yoki actor metodiga uzatilganda, u Sendable bo‘lishi kerak.
Kompilyator @Sendable yopilmasining sinflarga o‘zgaruvchan havolalarni tutib olmasligini tekshiradi. Sendable turlarining let xususiyatlarini tutib olishga ruxsat beriladi. Malumot turining var o‘zgaruvchisini tutib olish xatoga sabab bo‘ladi, chunki yopilma mutatsiya bilan bir vaqtda bajarilishi mumkin.
func performAsync(operation: @Sendable () -> Void) {
Task {
await operation()
}
}
let constant = "Safe"
var counter = 0
// counter — var ni tutib olish hisoblagichni mutatsiya qiladi, kompilyatsiya xatosi
performAsync { // ❌ Tutib olingan var ning mutatsiyasi
print(constant)
}
Qoida oddiy: @Sendable yopilmasi faqat o‘zi Sendable bo‘lgan va tashqaridan mutatsiya qilinmaydigan ma’lumotlarni tutib olishi mumkin. Sinflar uchun, agar sinf Sendable deb belgilanmagan bo‘lsa, weak self zaif havolasini tutib olishga ruxsat beriladi. Bu klassik retain cycle va race condition ni oldini oladi.
Ko‘p so‘raladigan savollar
Sendable — bu kompilyatorga “Bu turni iplar o‘rtasida xavfsiz uzatish mumkin” deydigan marker. Strukturalar va konstantalar odatda standart bo‘yicha Sendable, sinflar — yo‘q, agar aniq ko‘rsatilmagan bo‘lsa.
Qiymat turlari (struct, enum) Sendable xususiyatlari bilan, o‘zgaruvchan holatga ega final sinflar, shuningdek barcha Swift asosiy turlari: Int, String, Double, Bool, Array, Dictionary, Optional — avtomatik ravishda Sendable-ga mos keladi.
@unchecked Sendable — bu kompilyatorning statik tekshiruvisiz sinfni Sendable deb e’lon qilish usuli. Dasturchi xavfsizlikni mustaqil ravishda, ko‘pincha qulflar yoki atom operatsiyalar orqali kafolatlaydi.
Actor o‘z holatini izolyatsiya qiladi, lekin ma’lumotlarni tashqi kodga qaytarayotganda, bu ma’lumotlar izolyatsiya chegarasini kesib o‘tadi. Sendable qabul qiluvchining ushbu ma’lumotlardan actor tashqarisida foydalanishda poygalarga duch kelmasligini kafolatlaydi.
Barcha xususiyatlari Sendable turlarining konstantalari bo‘lgan final sinfga Sendable protokolini qo‘shing. Agar sinf qulflardan foydalansa, @unchecked Sendable ni qo‘llash mumkin, ammo bu ehtiyotkorlik talab qiladi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.