some View — Swift-in əsas sintaktik konstruksiyasıdır, onsuz SwiftUI işi mümkün deyil. Apple Swift Book, 2024-ə görə, some View qeyri-şəffaf tipdir (opaque type), o, qaytarılan dəyərin konkret tipini gizlədir, eyni zamanda kompilasiya mərhələsində ciddi tipizasiyanı qoruyur. Bu konstruksiya View protokolunun vahid body imzasına malik olmasına imkan verir, implementasiya detallarını açıqlamadan.
Əsas məqamlar
some View — Swift 5.1-də təqdim edilən qeyri-şəffaf tip (opaque type) sintaksisidir. View protokolunun body xassəsinin qayıdış tipi kimi istifadə olunur. some View yazılışı o deməkdir: «funksiya və ya xassə View protokoluna uyğun gələn bəzi konkret tipi qaytarır, lakin çağıran kod hansı tip olduğunu bilmir və bilməməlidir».
Qeyri-şəffaf tip anlayışı ümumiləşdirilmiş proqramlaşdırmanın (generics) əks tərəfidir. Generics çağıran koda tipi müəyyən etməyə imkan verirsə, opaque type implementasiyaya tipi müəyyən etməyə imkan verir, onu çağırandan gizlətməklə. Bu, proqramçıya daxili implementasiyanı kontraktı dəyişmədən dəyişmək azadlığı verir.
Swift Evolution SE-0244-ə görə, opaque types SwiftUI-ni və əlaqəli tipli protokollar (PAT) nümunəsini dəstəkləmək üçün əlavə edilmişdir, bu konstruksiya olmadan qayıdış tipi kimi istifadə edilə bilməz.
some View olmadan body imzası mümkün olmazdı: View protokolunun View-ə uyğun gələn əlaqəli Body tipi var. Əgər body sadəcə View (protokol kimi) qaytarsaydı, Swift Self requirements olan protokollarla qayıdış mövqeyində işləyə bilməzdi. some View bu problemi həll edir, konkret, lakin gizli tip təmin etməklə.
Qeyri-şəffaf tip (opaque type) — kompilator üçün konkret, proqramçı üçün isə abstrakt davranan xüsusi tip növüdür. Kompilator some View gördükdə implementasiyanı analiz edir və dəqiq qayıdış tipini müəyyənləşdirir. Bu tip müəyyən edilir və dinamik göndərmə olmadan kod generasiyası üçün istifadə olunur.
struct SimpleView: View {
var body: some View {
Text("Salam")
}
}
// Kompilator görür: body -> Text, some View deyil
İş prinsipi: Swift kompilatoru implementasiyadan konkret tipi çıxarır. Yuxarıdakı nümunədə body-nin məzmunu yalnız Text ehtiva edir, buna görə kompilator body-nin məhz Text qaytardığını bilir, imza some View kimi yazılsa da. Bu, iki optimallaşdırma verir: virtual metodlar cədvəli olmadan birbaşa çağırış və inline etmə imkanı.
Əgər body implementasiyası dəyişərsə (məsələn, Text əvəzinə VStack qaytarılarsa), kompilator konkret tipi yenidən müəyyənləşdirir. Lakin çağıran kod (SwiftUI) üçün imza eyni qalır — some View. Bu, generics-in əks tərəfidir: çağıran kod implementasiya dəyişikliklərindən asılı deyil.
Opaque type-in əsas qaydalarından biri: some View qaytaran funksiya və ya xassə həmişə eyni konkret tipi qaytarmalıdır. if-in bir qolunda Text, digərində isə Image qaytarmaq olmaz. Bu məhdudiyyət kompilator tərəfindən yoxlanılır və çağıran kod üçün zəmanətdir.
struct BadView: View {
var flag: Bool
var body: some View {
if flag {
Text("Doğru") // Xəta: Text vs VStack
} else {
VStack {
Text("Yanlış")
Image(systemName: "xmark")
}
}
}
}
Bu problemin həlli üçün @ViewBuilder istifadə olunur, o, müxtəlif qolları ConditionalContent şərti konteynerinə bükür. body üzərində @ViewBuilder annotasiyası — SwiftUI-də standart təcrübədir, body yalnız bir ifadə ehtiva edərsə, qeyri-müəyyən ola bilər.
AnyView — View-in konkret implementasiyasını silən tipdir (type erasure). İstənilən View-i vahid bir qablaşdırıcıya bükərək müxtəlif tipli View-ləri bir konteynerdə saxlamağa imkan verir. some View-dən fərqli olaraq, AnyView icra zamanı işləyir və qablaşdırma/boşaltma üçün əlavə yük əlavə edir.
| Meyar | some View | AnyView |
|---|---|---|
| Həll vaxtı | kompilasiya | icra |
| Performans | birbaşa çağırış, yüksüz | existential container-də qablaşdırma |
| Tip elastikliyi | bir konkret tip | istənilən View tipləri |
| Dinamik dəyişmə | dəstəklənmir | runtime-də dəstəklənir |
| İstifadə prioriteti | həmişə mümkün olduqda | yalnız some View mümkün olmadıqda |
| PAT protokolları dəstəyi | bəli | bəli |
AnyView nə vaxt istifadə edilməlidir: yalnız icra zamanı tipin dinamik dəyişməsi tələbi səbəbindən some View-in mümkün olmadığı hallarda. Məsələn, lüğətdən View qaytararkən və ya konkret tipin hər səviyyədə dəyişməli olduğu rekursiv strukturlarda. AnyView minimuma endirilməlidir, çünki hər qablaşdırma SwiftUI optimallaşdırmalarını söndürür.
Səhv fikir: AnyView body-dəki müxtəlif tiplər problemini həll etmir — bu problemi @ViewBuilder həll edir. AnyView tipi silir, lakin kompilatora vahid tip çıxarmağa kömək etmir. Şərti məntiq üçün @ViewBuilder-dən, dinamik göndərmə üçün isə yalnız AnyView-dən istifadə edin.
@ViewBuilder — some View ilə iş üçün xüsusi yaradılmış result builder-dir. Body-nin məzmununda şərti məntiq (if/else, switch) və çoxsaylı ifadələrdən istifadə etməyə imkan verir, vahid qayıdış tipini qoruyaraq. ViewBuilder avtomatik olaraq çoxsaylı ifadələri TupleView-ə, şərti qolları isə ConditionalContent-ə bükür.
struct ProfileView: View {
let user: User?
@ViewBuilder
var body: some View {
if let user {
UserCard(user: user)
Text("Online")
.font(.caption)
} else {
ProgressView("Loading...")
}
}
}
Bu necə işləyir: @ViewBuilder kod blokunu analiz edir və buildBlock, buildOptional və ya buildEither-in müvafiq çağırışını yaradır. Şərti məntiq üçün ConditionalContent yaradılır — qolların daxilindəki konkret tipləri gizlədən, lakin özü kompilator üçün vahid tip olan ümumi tip. Bu, müxtəlif konkret tiplər problemini həll edir.
@ViewBuilder olmadan çoxsaylı ifadələr və ya şərti məntiq ehtiva edən body xassəsi kompilasiya xətasına səbəb olardı. Məhz buna görə SwiftUI body-ə @ViewBuilder-i qeyri-müəyyən şəkildə tətbiq edir, özəl xassələr və funksiyalar üçün isə onu açıq şəkildə əlavə etmək lazımdır.
@ViewBuilder yerləşdirilə bilər: bir ViewBuilder digərinin daxilində. Bu, müxtəlif səviyyələrdə şərtlərlə mürəkkəb iyerarxiyalar yaratmağa imkan verir. Lakin dərin yerləşdirmə oxunaqlılığı çətinləşdirir, buna görə yerləşdirilmiş şərtləri ayrıca View komponentlərinə çıxarmaq tövsiyə olunur.
Nümunə 1: hesablanan xassədən xüsusi View-in qaytarılması. Xassə some View qaytara bilər, daxili kompozisiyanı gizlətməklə. Bu, kodu ictimai interfeysi dəyişmədən yenidən təşkil etməyə imkan verir.
struct ArticleView: View {
var body: some View {
CardView {
HeaderView()
ContentView()
FooterView()
}
}
}
struct CardView<Content: View>: View {
let content: Content
var body: some View {
content
.padding(16)
.background(.white)
.cornerRadius(12)
.shadow(radius: 4)
}
}
Nümunə 2: @ViewBuilder vasitəsilə View-in qapanma kimi ötürülməsi. Bu nümunə SwiftUI-nin standart konteynerlərində (VStack, HStack, List) istifadə olunur və özəl komponentlərdə tətbiq edilə bilər.
struct CustomContainer<Content: View>: View {
@ViewBuilder let content: () -> Content
var body: some View {
VStack(alignment: .leading) {
content()
}
.padding(20)
}
}
Nümunə 3: some View qaytaran fabrik funksiyası. Implementasiyanı açıqlamadan parametrlərdən asılı olaraq View yaratmağa imkan verir. Bu, xüsusilə kitabxanalar və təkrar istifadə olunan komponentlər üçün faydalıdır.
func makeIcon(for status: Status) -> some View {
switch status {
case .success:
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
case .error:
Image(systemName: "xmark.circle.fill")
.foregroundColor(.red)
case .pending:
ProgressView()
}
}
Tez-tez verilən suallar
some View — qeyri-şəffaf tipdir (opaque type), yəni View protokoluna uyğun gələn bəzi konkret tip qaytarılır. Konkret tip kompilator tərəfindən müəyyən edilir, lakin çağıran koddan gizlədilir. Bu, implementasiya detallarını açıqlamadan ciddi tipizasiyanı təmin edir.
some View kompilasiya mərhələsində sıfır yüklə həll edilir. AnyView icra zamanı existential container-də qablaşdırma üçün əlavə xərclərlə tip silmədən (type erasure) istifadə edir. Mümkün olduqda həmişə some View-dən, tipin dinamik dəyişməsi üçün isə yalnız AnyView-dən istifadə edin.
Qeyri-şəffaf tip bütün qayıdış yolları üçün vahid konkret tip tələb edir. Müxtəlif tiplərlə if/else bu tələbi pozur. @ViewBuilder qolları ConditionalContent-ə bükərək problemi həll edir — konkret implementasiyaların fərqlərini gizlədən vahid tip.
some View performansı azaltmır — kompilator dəqiq tipi bilir və birbaşa kod yaradır. Əksinə, any View (protokol kimi) dinamik göndərmə tələb edərdi. some View — SwiftUI dizaynına daxil edilmiş optimallaşdırma mexanizmidir.
Bəli, some — Swift 5.1-in ümumi konstruksiyasıdır, SwiftUI-ə bağlı deyil. İstənilən protokolla istifadə edilə bilər: some Equatable, some Codable, some Collection. Bu, [String: [Int]] kimi mürəkkəb yerləşdirilmiş tipləri gizlətmək üçün faydalıdır.
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