Body xususiyati — SwiftUI da View protokolining markaziy elementi bo'lib, ekranda qanday tarkib ko'rsatilishini belgilaydi. Apple Developer Documentation, 2024 ga ko'ra, body View protokolining yagona majburiy talabidir va shu protokolga mos keladigan turni qaytaradi. SwiftUI har bir holat o'zgarishida yangi elementlar daraxtini qurish va solishtirish uchun body ni chaqiradi.
Asosiy fikrlar
body — View protokolining yagona majburiy talabi bo'lgan hisoblanuvchi xususiyatdir (computed property). View ga mos keladigan har bir struktura body ni amalga oshirishi kerak. Xususiyat SwiftUI ekranda ko'rsatadigan tarkibni qaytaradi — bu matn, tasvir, tugma, ichki elementlarga ega konteyner yoki View protokoliga mos keladigan boshqa har qanday tur bo'lishi mumkin.
Body ning imzosi har doim turg'un: var body: some View { get }. Qaytarilgan tur — some View (shaffof bo'lmagan tur), aniq tur emas. Bu turli View lar body da turli aniq turlarni qaytarishi mumkinligini anglatadi, lekin Swift kompilyatori har bir amalga oshirish uchun aniq turni kompilyatsiya bosqichida belgilaydi.
WWDC 2022 ga ko'ra, body interfeysning deklarativ tavsifiga kirish nuqtasidir. UIKit dan farqli o'laroq, siz UIView ni imperativ tarzda yaratib sozlaysiz, SwiftUI da siz nima ko'rsatilishi kerakligini deklarativ tarzda tavsiflaysiz, SwiftUI esa buni qanday amalga oshirishni o'zi hisoblaydi.
body sof funksiya kabi harakat qilishi kerak — bir xil kirish ma'lumotlarida (struktura xususiyatlari va holat) bir xil View daraxtini qaytarishi kerak. Agar body tashqi o'zgaruvchan holatga (global o'zgaruvchilar, @AppStorage o'ramisiz UserDefaults) bog'liq bo'lsa, harakat oldindan aytib bo'lmaydigan bo'ladi va SwiftUI ekranni noto'g'ri qayta chizishi mumkin.
Hisoblanuvchi xususiyat body qiymatni saqlamaydi — har murojaatda hisoblanadi. SwiftUI holat o'zgarganligini aniqlaganda, View strukturasini qayta yaratadi va ko'rsatish uchun dolzarb elementlar daraxtini olish uchun body ning yangi qiymatini o'qiydi.
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Hisoblagich: \(count)")
.font(.largeTitle)
Button("Oshirish") {
count += 1
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
Ushbu misolda body modifikatorlarga ega Text va tugmani o'z ichiga olgan VStack ni qaytaradi. Tugma bosilganda @State xususiyati count ortadi, SwiftUI CounterView strukturasini qayta yaratadi va Text ning yangi qiymati bilan yangilangan daraxtni olish uchun body ni qayta chaqiradi.
Modifikatorlar (.font, .padding, .background, .foregroundColor, .cornerRadius) asl View ni o'zgartirmaydi, balki uni ModifiedContent ga o'raydi — modifikatsiya qo'shadigan yangi tur. Har bir modifikator yana bir ichki joylashish darajasini yaratadi, bu esa ishlash uchun hisobga olinishi kerak.
some View body ning qaytarish turida — bu shunchaki konvensiya emas, balki kompilyatorning majburiy talabidir. Swift body dagi barcha qaytish yo'llari bir xil aniq turga ega bo'lishini talab qiladi. @ViewBuilder siz bir tarmoqqa Text va boshqasiga Button qaytara olmaysiz — kompilyator xato beradi.
struct ConditionalView: View {
var isReady: Bool
@ViewBuilder
var body: some View {
if isReady {
Text("Tayyor")
.foregroundColor(.green)
} else {
ProgressView()
}
}
}
@ViewBuilder body da shartli mantiqdan (if/else, switch) kompilyatsiya xatolarisiz foydalanishga imkon beradi. ViewBuilder avtomatik ravishda turli tarmoqlarni ConditionalContent ga o'raydi — aniq turlarning farqlarini yashiradigan maxsus tur. Bu dinamik interfeyslarni qurish uchun asosiy imkoniyatdir.
@ViewBuilder siz kompilyator barcha qaytish yo'llari uchun yagona turni chiqarishga harakat qiladi. Turlar farqli bo'lsa — xato yuz beradi. Shuning uchun SwiftUI View deklaratsiyalarida body ga yashirincha @ViewBuilder qo'llaydi, garchi foydalanuvchi kodida bir nechta View qaytaradigan maxsus metodlar va xususiyatlar uchun annotatsiyani aniq qo'yish kerak.
some View dan aniq tur o'rniga foydalanish ishlashni kamaytirmaydi — kompilyator kompilyatsiya bosqichida aniq turni biladi va dinamik dispetcherizatsiyasiz to'g'ridan-to'g'ri kod yaratadi. AnyView esa ekzistensial konteynerga paketlash qo'shimcha yuki bilan tur o'chirishdan (type erasure) foydalanadi.
body SwiftUI tomonidan uchta asosiy ssenariyda chaqiriladi: View birinchi ko'rsatilganda, @State/@Binding/@ObservedObject/@StateObject o'zgarganda va yangi qiymatlarni inizializator orqali uzatuvchi ota-ona View o'zgarganda. SwiftUI shuningdek atrof-muhit qiymatlari (@Environment) o'zgarganda body ni chaqirishi mumkin.
Body ni chaqirish chastotasi sizni tashvishga solmasligi kerak — SwiftUI identifikatsiya mexanizmi orqali qayta chizishni optimallashtiradi. Ierarxiyadagi har bir View noyob identifikatorga ega. Agar identifikatsiya va kirish ma'lumotlari o'zgarmagan bo'lsa — body chaqirilmaydi, hatto ota-ona View qayta chizilgan bo'lsa ham. Bunga Equatable taqqoslash va strukturalarning barqarorligi orqali erishiladi.
struct ParentView: View {
var body: some View {
ChildView(name: "Alice") // Barqaror identifikatsiya
}
}
struct ChildView: View {
let name: String
var body: some View {
Text("Salom, \(name)!")
}
}
Ushbu misolda, ParentView qayta chizilsa, lekin bir xil name qiymatini uzatsa — ChildView.body chaqirilmaydi. SwiftUI strukturaning kirish ma'lumotlarini taqqoslaydi va agar ular o'zgarmagan bo'lsa, bola komponentining qayta chizilishini o'tkazib yuboradi. Bu view differentsiatsiyasi (view differentiation) mexanizmidir.
Body ning kutilmaganda chaqirilishiga olib keladigan bir nechta tuzoq bor: ObservableObject siz sinflardan foydalanish, body ichida yaratilgan yopilishlarni uzatish (har bir yopilish yaratilishi yangi identifikatsiya beradi) va EquatableView dan noto'g'ri foydalanish. Agar body juda tez-tez chaqirilsa — barcha bola komponentlarining identifikatsiya barqarorligini tekshiring.
Birinchi qoida: body minimal bo'lishi kerak. Murakkab mantiqni alohida hisoblanuvchi xususiyatlarga yoki View qaytaradigan metodlarga chiqaring. Bu o'qishni yaxshilaydi va SwiftUI ga ierarxiyaning qaysi qismlari o'zgarganligini aniqroq aniqlashga imkon beradi. Katta body larni aniq mas'uliyat chegaralariga ega bo'lgan pastki komponentlarga bo'ling.
Ikkinchi qoida: body ni ish bajarish uchun ishlatmang. Ma'lumot yuklash, tarmoq bilan ishlash, ma'lumotlar bazasiga yozish — bularning barchasi body dan tashqarida, topshiriqlarda (task), onChange modifikatorlarida yoki ObservableObject orqali amalga oshirilishi kerak. body faqat interfeys deklaratsiyasi uchun mo'ljallangan.
Uchinchi qoida: strukturalarning standart taqqoslashi yetarli bo'lmasa, View uchun EquatableView xususiyatidan yoki maxsus Equatable protokolidan foydalaning. Bu SwiftUI ga bola View qachon qayta chizishni talab qilishini aniq ko'rsatishga va keraksiz body chaqiruvlaridan qochishga imkon beradi.
To'rtinchi qoida: agar body murakkab hisoblashlarni (formatlash, filtrlash, saralash) o'z ichiga olsa — natijani keshlash uchun @State dan foydalaning yoki hisoblashlarni onChange dan chaqiriladigan alohida metodga chiqaring. Har bir holat yangilanishida body da takroriy hisoblashlar animatsiya sekinlashuvining keng tarqalgan sababidir.
Beshinchi qoida: ro'yxatlar uchun (List, ForEach) id parametri orqali barqaror identifikatorlarni ta'minlang. Barqaror identifikatsiyasiz ForEach har bir o'zgarishda barcha elementlarni qayta yaratadi, faqat bitta element o'zgargan bo'lsa ham, ularning har biri uchun body ni chaqiradi.
Tez-tez beriladigan savollar
body — View protokolining hisoblanuvchi xususiyati bo'lib, ko'rsatish uchun tarkibni qaytaradi. Bu protokolning yagona majburiy talabidir. Qaytarilgan tur — some View, bu SwiftUI ga kompilyatsiya bosqichida ierarxiyani optimallashtirishga imkon beradi.
Ha, SwiftUI body ni har bir holat o'zgarishida (@State, @Binding, @ObservedObject) yoki kirish ma'lumotlari o'zgarganda chaqiradi. Bu deklarativ freymvork uchun normal xatti-harakatdir. SwiftUI identifikatsiya mexanizmi va Equatable taqqoslash orqali chaqiruvlar chastotasini optimallashtiradi.
some View — aniq amalga oshirishni yashirishga imkon beruvchi shaffof bo'lmagan tur. Kompilyator turni kompilyatsiya bosqichida belgilaydi, to'g'ridan-to'g'ri chaqiruv ishlashini ta'minlaydi. Bu moslashuvchanlik beradi: imzoni o'zgartirmasdan qaytarilgan turni o'zgartirish mumkin.
Yo'q, body ixtiyoriy bo'lishi mumkin emas — qaytarilgan tur some View nil ga ruxsat bermaydi. Agar elementni shartli ravishda yashirish kerak bo'lsa, @ViewBuilder ichida shartli mantiqdan foydalaning yoki ierarxiyada joy egallamaydigan EmptyView ni qaytaring.
Har bir modifikator ierarxiya chuqurligini oshiradigan yangi ModifiedContent qatlamini yaratadi. Ko'pchilik ekranlar uchun (50 modifikatorgacha) ta'sir sezilmaydi. Haddan tashqari ko'p modifikatorlar (yuzlab) diffing ni sekinlashtirishi mumkin. Bog'liq modifikatorlarni maxsus kengaytmalarda guruhlang.
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.