Widoki Equatable i zakres @State
Zawężanie stanu w celu ograniczenia unieważniania widoków.
Widoki Equatable i zakres @State to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Równość pozwala pominąć obliczenia
Jeśli SwiftUI może potwierdzić, że dane wejściowe widoku się nie zmieniły, może pominąć jego ponowne renderowanie. Uczynienie widoku Equatable daje SwiftUI precyzyjny sposób podjęcia tej decyzji.
Zgodność z Equatable
Należy zapewnić zgodność widoku z Equatable, aby SwiftUI porównywało stare i nowe wartości. Jeśli są równe, pomija obliczanie właściwości body.
struct Badge: View, Equatable {
let count: Int
var body: some View { Text("\(count)") }
static func == (a: Badge, b: Badge) -> Bool {
a.count == b.count
}
}EquatableView
Można również opakować dowolny widok Equatable za pomocą .equatable(), aby zażądać pomijania na podstawie porównania bez zmieniania miejsc wywołania tego typu w całym kodzie.
Badge(count: total)
.equatable()Kiedy Equatable pomaga
Equatable najlepiej sprawdza się w widokach, których dane wejściowe można szybko porównać, ale których właściwość body jest kosztowna. Koszt porównania musi być znacznie niższy od kosztu renderowania, aby takie rozwiązanie się opłacało.
Pułapka kosztu porównania
Jeśli samo == jest kosztowne (na przykład wykonuje głębokie porównanie dużych tablic), może kosztować więcej niż renderowanie, którego próbują Państwo uniknąć. Należy porównywać tylko tanie w porównaniu, rozstrzygające pola.
static func == (a: Self, b: Self) -> Bool {
a.id == b.id && a.version == b.version // cheap fields
}Domyślnie generowana implementacja Equatable
Jeśli wszystkie przechowywane właściwości są typu Equatable, Swift może automatycznie wygenerować ==. Domknięcia i niektóre typy nie są jednak typu Equatable, dlatego może być potrzebna własna implementacja, która je pomija.
struct Card: View, Equatable {
let title: String
let onTap: () -> Void // not Equatable
static func == (a: Card, b: Card) -> Bool { a.title == b.title }
var body: some View { Text(title) }
}Zawężanie zakresu @State
Stan umieszczony zbyt wysoko powoduje ponowne renderowanie wszystkiego, co znajduje się poniżej. Należy przenieść @State do najmniejszego widoku, który jest jego właścicielem, aby zmiany wpływały na jak najmniejszą część interfejsu.
// Move toggle state into the row that uses it
struct Row: View {
@State private var expanded = false
var body: some View { /* only this row re-renders */ Text("Row") }
}Podnoszenie stanu tylko wtedy, gdy jest współdzielony
Stan należy podnosić wyżej tylko wtedy, gdy rzeczywiście potrzebuje go wiele widoków. W przeciwnym razie stan lokalny ogranicza zakres ponownego renderowania.
Wydzielanie podwidoków w celu lokalizowania aktualizacji
Wydzielenie często zmieniającego się elementu do osobnego widoku ogranicza ponowną ewaluację do tego widoku, pozostawiając widoki sąsiednie bez zmian.
struct LiveClock: View {
@State private var now = Date()
var body: some View { Text(now, style: .time) }
}Bindingi i zakres
@Binding łączy widok podrzędny ze stanem widoku nadrzędnego. Przekazywanie wąskiego bindingu (pojedynczego pola) zamiast całego obiektu ogranicza zakres propagowanych zmian.
struct NameField: View {
@Binding var name: String // narrow binding
var body: some View { TextField("Name", text: $name) }
}Połączenie Equatable z odpowiednim zakresem
Najlepsze rezultaty daje połączenie technik: zawężenie miejsca przechowywania stanu w celu ograniczenia wyzwalaczy oraz użycie Equatable do pomijania renderowań, które mimo wszystko zostaną uruchomione.
Szybki test: widoki Equatable
Proszę sprawdzić swoją wiedzę na temat widoków Equatable i zakresu stanu.
Podsumowanie: widoki Equatable i zakres stanu
Uczynienie widoku typu Equatable (lub użycie .equatable()) pozwala SwiftUI pomijać renderowanie widoków, które się nie zmieniły — jest to opłacalne, gdy porównanie jest znacznie tańsze od renderowania i obejmuje tylko rozstrzygające pola.
Należy zawęzić @State do najmniejszego widoku będącego jego właścicielem, przekazywać wąskie bindingi i wydzielać często zmieniające się elementy do osobnych widoków. Połączenie ścisłego zakresu stanu z Equatable zapewnia najmniejszą liczbę najtańszych ponownych renderowań.
Często zadawane pytania
Czy lekcja „Widoki Equatable i zakres @State” jest bezpłatna?
Tak — pełny tekst „Widoki Equatable i zakres @State” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Widoki Equatable i zakres @State”?
Zawężanie stanu w celu ograniczenia unieważniania widoków. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Widoki Equatable i zakres @State”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Zrozumienie tożsamości widoków
- Minimalizowanie ponownej ewaluacji body
- Widoki Equatable i zakres @State
- Profilowanie za pomocą instrumentu SwiftUI