Published on

Nima uchun view’larga State (Holat) kerak?

Authors

Tasavvur qiling, basketbol o'yinidagi tabloni kuzatyapsiz. Har safar jamoa ochko olganda, kimdir tablodagi raqamni yangilaydi. Ammo agar tablo hech narsaga ulanmagan bo'lsa-chi? Ya'ni, sahna ortida ochkoni o'zgartirish tabloga o'zini yangilash haqida xabar bera olmasa-chi? Tablodagi raqam muzlab qolaveradi, maydonda nima sodir bo'lishidan qat'i nazar o'zgarmaydi. SwiftUI-ning State (holat) tizimi aynan shu muammoni hal qiladi.

Stage 1-da siz xususiyatlar (properties), modifikatorlar va maket konteynerlari (layout containers) yordamida view'larni yaratdingiz. Ular juda yaxshi ishladi β€” lekin ularning barchasi view yaratilgan vaqtda qat'iy qilib belgilangan edi. Agar foydalanuvchi biror amalni bajarganda interfeys o'zgarishini xohlasangiz, tezda to'siqqa duch kelasiz.

Ushbu darsning oxirida siz oddiy o'zgaruvchi (variable) nima uchun o'zgarganda SwiftUI-da interfeysni yangilamasligini tushunib olasiz va State o'zi nima ekanligi hamda SwiftUI-ga nima uchun kerakligi haqida tasavvurga ega bo'lasiz. Ushbu darsda kod yozilmaydi β€” faqat Stage 2-dagi boshqa darslarni tushunishga yordam beradigan muhim konseptlar o'rganiladi.

Oddiy o'zgaruvchidan foydalanilganda nima sodir bo'ladi

Keling, muammoni aniq misolda ko'rib chiqaylik. Aytaylik, foydalanuvchi tugmani bosganda oshib boradigan hisoblagichni (counter) ko'rsatmoqchisiz. Sizda birinchi navbatda shunday kod yozish istagi paydo bo'lishi mumkin:

struct CounterView: View {
    // Oddiy o'zgaruvchi β€” @State bilan o'ralmagan
    var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button("Tap me") {
                // Bu qator kompilyatsiya xatosini keltirib chiqaradi β€” struct-lar o'zgarmasdir (immutable)
                count += 1
            }
        }
    }
}

Bu kod hatto kompilyatsiya ham bo'lmaydi. SwiftUI view'lari struct (struktura) hisoblanadi, struct'lar esa qiymat turlaridir (value types) β€” ularning xususiyatlari metodlar ichida o'zgartirib bo'lmaydigan (immutable) holatda bo'ladi. Ammo bu to'siqdan aylanib o'tgan taqdiringizda ham, bundan chuqurroq muammo bor: SwiftUI count o'zgaruvchisi o'zgarganini bilish imkoniga ega emas. U oddiy o'zgaruvchining o'zgarishini kuzatmaydi. Shuning uchun, o'zgarish sodir bo'lsa ham, SwiftUI yangi raqamni ko'rsatish uchun view'ni qayta chizmaydi (re-render).

Asosiy tushuncha: SwiftUI nima o'zgarganini bilish umidida har millisekundda view'ingizni qaytadan chizib turmaydi. U faqat biror narsa o'zgarganini aniq bilgandagina qayta chizadi. Buni bilishi uchun esa siz SwiftUI-ga aynan nimalarni kuzatish kerakligini bildiruvchi maxsus xususiyat o'ragichidan (property wrapper) foydalanishingiz kerak.

Source of truth" (haqiqat manbai) nima degani?

SwiftUI-da "source of truth" iborasini juda ko'p eshitasiz. Bu shunchaki: ma'lumotlar saqlanadigan bitta nufuzli, rasmiy joy deganidir. Ushbu ma'lumot o'zgarganda, unga bog'liq bo'lgan barcha narsalar avtomatik ravishda yangilanadi. View β€” bu ma'lumotning aksidir (aksincha emas).

Buni uyingizdagi termostat va har bir xonadagi displey misolida tasavvur qiling. Termostat haqiqiy harorat qiymatini saqlaydi (haqiqat manbai - source of truth). Har bir xonadagi displeylar esa shunchaki termostat nima deyotganini ko'rsatib beradi. Siz har bir xona displeyini alohida-alohida yangilamaysiz β€” termostatdagi haroratni o'zgartirasiz va qolgan displeylar avtomatik ravishda unga ergashadi.

SwiftUI-da State β€” bu sizning termostatingiz. View'laringiz esa xonalardagi displeylardir. State o'zgarganda, SwiftUI unga qaysi view'lar bog'liqligini aniqlaydi va faqat o'sha qismlarni qaytadan chizadi. Bu tizim reaktiv interfeyslarni (Reactive UI) yaratishga imkon beradi.

Kelajak uchun asosiy konseptual model

Keyingi darsda kod yozishni boshlashdan oldin, quyidagi modelni yodda tuting: SwiftUI view'i β€” bu uning holati (state) natijasidir (ya'ni view = f(state)). Bir xil holat uchun har doim bir xil view olasiz. Holatni o'zgartirsangiz, SwiftUI ushbu funksiyani qayta chaqiradi va yangi view yaratadi. Siz har qanday holat uchun interfeys qanday ko'rinishini tasvirlaysiz, qolganini esa SwiftUI-ning o'zi hal qiladi.

Nima uchun bu juda muhim: SwiftUI-da "UI yangilanmayapti" yoki "eski ma'lumotlar ko'rinyapti" kabi xatolarning barchasi aynan shu konseptga borib taqaladi. Agar "state-drives-view" (holat view'ni boshqaradi) aloqasini to'g'ri tushunib olsangiz, bunday xatolarni aniqlash va tuzatish juda oson bo'ladi.

Tezkor ma'lumotnoma

KonseptMa'nosi
Oddiy o'zgaruvchiStruct ichida o'zgartirib bo'lmaydi β€” o'zgargan taqdirda ham SwiftUI qayta chizish kerakligini bilmaydi.
State (Holat)SwiftUI kuzatib boradigan ma'lumot β€” u o'zgarganda bog'liq view'lar avtomatik yangilanadi.
Source of TruthMa'lumot saqlanadigan va egalik qilinadigan yagona rasmiy joy.
View funksiya sifatidaBir xil holat (state) har doim bir xil view'ni beradi β€” UI-ni o'zgartirish uchun holatni o'zgartiring.
Reaktiv UIInterfeysni qo'lda yangilash o'rniga, u ma'lumot o'zgarishiga avtomatik reaksiyaga kirishadi.

Topshiriq: muammoni aniqlang

Davom etishdan oldin, buni Xcode-da sinab ko'ring. ScoreboardView deb nomlangan yangi SwiftUI view yarating. var score = 0 xususiyatini qo'shing va score += 1 bajarishga urinadigan Button yarating. Kompilyatordan qanday xatolik olishingizni o'qing. Keyin tugmaning closure qismiga mutating kalit so'zini qo'shib ko'ring (buni qila olmaysiz β€” chunki closure struct ichidagi metod emas). Maqsad β€” oddiy o'zgaruvchilar nima uchun ishlamasligini ko'rish va keyingi @State (Mahalliy View Holati) darsidagi yechimni chuqurroq tushunishdir.

Maslahat: Kompilyatordagi "cannot assign to property: 'self' is immutable" xatosini qidiring. Uni diqqat bilan o'qing β€” u sizga muammo nimada ekanligini aytib beradi.

Buy mea coffee