Body xassəsi — SwiftUI-də View protokolunun mərkəzi elementi olub, ekranda hansı məzmunun göstərildiyini müəyyən edir. Apple Developer Documentation, 2024-ə görə, body View protokolunun yeganə məcburi tələbidir və bu protokola uyğun bir tip qaytarır. SwiftUI hər vəziyyət dəyişikliyində yeni element ağacı qurmaq və müqayisə etmək üçün body-ni çağırır.
Əsas məqamlar
body — View protokolunun yeganə məcburi tələbi olan hesablanan xassədir (computed property). View-ə uyğun gələn hər bir struktur body-ni tətbiq etməlidir. Xassə SwiftUI-nin ekranda göstərdiyi məzmunu qaytarır — bu mətn, şəkil, düymə, iç-içə elementləri olan konteyner və ya View protokoluna uyğun hər hansı başqa tip ola bilər.
Body-nin imzası həmişə sabitdir: var body: some View { get }. Qaytarılan tip — some View (qeyri-şəffaf tip), konkret tip deyil. Bu o deməkdir ki, müxtəlif View-lər body-də müxtəlif konkret tiplər qaytara bilər, lakin Swift kompilyatoru hər tətbiq üçün konkret tipi kompilyasiya mərhələsində müəyyən edir.
WWDC 2022-yə görə, body interfeysin deklarativ təsviri üçün giriş nöqtəsidir. UIKit-də siz UIView-i imperativ şəkildə yaradıb konfiqurasiya edirsinizsə, SwiftUI-də siz nəyin göstərilməli olduğunu deklarativ şəkildə təsvir edirsiniz, SwiftUI isə bunu necə həyata keçirəcəyini özü hesablayır.
body təmiz funksiya kimi davranmalıdır — eyni giriş məlumatlarında (struktur xassələri və vəziyyət) eyni View ağacını qaytarmalıdır. Əgər body xarici dəyişən vəziyyətdən (qlobal dəyişənlər, @AppStorage bürüməsi olmayan UserDefaults) asılıdırsa, davranış proqnozlaşdırıla bilməz və SwiftUI ekranı səhv şəkildə yenidən çəkə bilər.
Hesablanan xassə body dəyər saxlamır — hər müraciətdə hesablanır. SwiftUI vəziyyətin dəyişdiyini müəyyən etdikdə, View strukturunu yenidən yaradır və göstərilmək üçün aktual element ağacını əldə etmək üçün body-nin yeni dəyərini oxuyur.
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Sayğac: \(count)")
.font(.largeTitle)
Button("Artır") {
count += 1
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
Bu nümunədə body modifikatorları olan Text və düyməni ehtiva edən VStack qaytarır. Düymə basıldıqda @State xassəsi count artır, SwiftUI CounterView strukturunu yenidən yaradır və Text-in yeni dəyəri ilə yenilənmiş ağacı əldə etmək üçün body-ni yenidən çağırır.
Modifikatorlar (.font, .padding, .background, .foregroundColor, .cornerRadius) orijinal View-i dəyişmir, onu ModifiedContent ilə bürüyür — modifikasiya əlavə edən yeni tip. Hər modifikator daha bir iç-içəlik səviyyəsi yaradır ki, bu da performans üçün nəzərə alınmalıdır.
some View body-nin qaytarma tipində — bu sadəcə konvensiya deyil, kompilyatorun məcburi tələbidir. Swift tələb edir ki, body-dəki bütün qaytarma yollarının eyni konkret tipi olsun. @ViewBuilder olmadan bir qolda Text, digər qolda Button qaytara bilməzsiniz — kompilyator xəta verəcək.
struct ConditionalView: View {
var isReady: Bool
@ViewBuilder
var body: some View {
if isReady {
Text("Hazırdır")
.foregroundColor(.green)
} else {
ProgressView()
}
}
}
@ViewBuilder body-də şərti məntiqdən (if/else, switch) kompilyasiya xətaları olmadan istifadə etməyə imkan verir. ViewBuilder avtomatik olaraq müxtəlif qolları ConditionalContent-də bürüyür — konkret tiplərin fərqlərini gizlədən xüsusi tip. Bu dinamik interfeyslər qurmaq üçün əsas imkandır.
@ViewBuilder olmadan kompilyator bütün qaytarma yolları üçün vahid tip çıxarmağa çalışır. Tiplər fərqlidirsə — xəta yaranır. Buna görə SwiftUI View deklarasiyalarında body-yə gizli şəkildə @ViewBuilder tətbiq edir, baxmayaraq ki, istifadəçi kodunda bir neçə View qaytaran xüsusi metodlar və xassələr üçün annotasiyanı açıq şəkildə qoymaq lazımdır.
some View istifadəsi konkret tip əvəzinə performansı azaltmır — kompilyator kompilyasiya mərhələsində dəqiq tipi bilir və dinamik dispetçerizasiya olmadan birbaşa kod yaradır. AnyView isə ekzistensial konteynerə paketləmə əlavə yükü ilə tip silmə (type erasure) istifadə edir.
body SwiftUI tərəfindən üç əsas ssenaridə çağırılır: View-in ilk göstərilməsində, @State/@Binding/@ObservedObject/@StateObject dəyişikliyində və valideyn View-in inizializator vasitəsilə yeni dəyərlər ötürməsində. SwiftUI həmçinin ətraf mühit dəyərləri (@Environment) dəyişdikdə body-ni çağıra bilər.
Body-nin çağırılma tezliyi sizi narahat etməməlidir — SwiftUI kimlik mexanizmi vasitəsilə yenidən çəkməyi optimallaşdırır. İerarxiyada hər View-in unikal identifikatoru var. Kimlik və giriş məlumatları dəyişməyibsə — body çağırılmır, hətta valideyn View yenidən çəkilsə belə. Buna Equatable müqayisəsi və strukturların sabitliyi ilə nail olunur.
struct ParentView: View {
var body: some View {
ChildView(name: "Alice") // Sabit kimlik
}
}
struct ChildView: View {
let name: String
var body: some View {
Text("Salam, \(name)!")
}
}
Bu nümunədə, ParentView yenidən çəkilsə, lakin eyni name dəyərini ötürsə — ChildView.body çağırılmır. SwiftUI strukturun giriş məlumatlarını müqayisə edir və dəyişməyiblərsə, uşaq komponentinin yenidən çəkilməsini keçir. Bu view diferensiasiyası (view differentiation) mexanizmidir.
Body-nin gözlənilmədən çağırılmasına səbəb olan bir neçə tələ var: ObservableObject olmadan siniflərdən istifadə, body daxilində yaradılan kllözlərin ötürülməsi (hər kllöz yaradılması yeni kimlik verir) və EquatableView-in səhv istifadəsi. Body çox tez-tez çağırılırsa — bütün uşaq komponentlərinin kimlik sabitliyini yoxlayın.
Birinci qayda: body minimal olmalıdır. Mürəkkəb məntiqi ayrı hesablanan xassələrə və ya View qaytaran metodlara çıxarın. Bu oxunaqlılığı yaxşılaşdırır və SwiftUI-yə ierarxiyanın hansı hissələrinin dəyişdiyini daha dəqiq müəyyən etməyə imkan verir. Böyük body-ləri aydın məsuliyyət sərhədləri olan alt komponentlərə bölün.
İkinci qayda: body-ni iş görmək üçün istifadə etməyin. Məlumat yükləmə, şəbəkə ilə iş, verilənlər bazasına yazı — bütün bunlar body-dən kənarda, tapşırıqlarda (task), onChange modifikatorlarında və ya ObservableObject vasitəsilə baş verməlidir. body yalnız interfeysin deklarasiyası üçün nəzərdə tutulub.
Üçüncü qayda: strukturların standart müqayisəsi kifayət deyilsə, View üçün EquatableView xassəsindən və ya xüsusi Equatable protokolundan istifadə edin. Bu, SwiftUI-yə uşaq View-in nə vaxt yenidən çəkilmə tələb etdiyini açıq şəkildə göstərməyə və lazımsız body çağırışlarından qaçmağa imkan verir.
Dördüncü qayda: əgər body mürəkkəb hesablamalar (formatlaşdırma, filtrləmə, sıralama) ehtiva edirsə — nəticəni keşləmək üçün @State istifadə edin və ya hesablamaları onChange-dən çağırılan ayrı metoda çıxarın. Hər vəziyyət yenilənməsində body-də təkrar hesablamalar animasiya ləngimələrinin ümumi səbəbidir.
Beşinci qayda: siyahılar üçün (List, ForEach) id parametri vasitəsilə sabit identifikatorlar təmin edin. Sabit kimlik olmadan ForEach hər dəyişiklikdə bütün elementləri yenidən yaradır, yalnız bir element dəyişsə belə, hər biri üçün body-ni çağırır.
Tez-tez verilən suallar
body — View protokolunun hesablanan xassəsi olub, göstərilmək üçün məzmun qaytarır. Bu protokolun yeganə məcburi tələbidir. Qaytarılan tip — some View ki, bu da SwiftUI-yə kompilyasiya mərhələsində ierarxiyanı optimallaşdırmağa imkan verir.
Bəli, SwiftUI body-ni hər vəziyyət dəyişikliyində (@State, @Binding, @ObservedObject) və ya giriş məlumatları dəyişdikdə çağırır. Bu deklarativ freymvork üçün normal davranışdır. SwiftUI kimlik mexanizmi və Equatable müqayisəsi vasitəsilə çağırış tezliyini optimallaşdırır.
some View — konkret tətbiqi gizlətməyə imkan verən qeyri-şəffaf tipdir. Kompilyator tipi kompilyasiya mərhələsində təsbit edir, birbaşa çağırış performansını təmin edir. Bu çeviklik verir: imzanı dəyişmədən qaytarılan tipi dəyişmək olar.
Xeyr, body optional ola bilməz — qaytarılan tip some View nil-ə icazə vermir. Əgər elementi şərti olaraq gizlətmək lazımdırsa, @ViewBuilder daxilində şərti məntiqdən istifadə edin və ya ierarxiyada yer tutmayan EmptyView qaytarın.
Hər modifikator ierarxiyanın dərinliyini artıran yeni ModifiedContent qatı yaradır. Əksər ekranlar üçün (50 modifikatora qədər) təsir hiss olunmaz. Həddindən artıq modifikatorlar (yüzlərlə) diffing-i ləngidə bilər. Əlaqəli modifikatorları xüsusi genişlənmələrdə qruplaşdırın.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun