@StateObject: bu nədir, ObservableObject-in yaradılması və idarə edilməsi

Müəllif: IT Sectr Dərc olunub: 2026-06-26 Oxuma vaxtı: 9 dəq

@StateObject — SwiftUI-də View-in bütün həyat dövrü ərzində ObservableObject nümunəsini yaradan və ona sahib olan property wrapper-dır. View ilk dəfə ekranda görünəndə, @StateObject obyekti inisializasiya edir və View yaddaşdan silinənə qədər onu saxlayır. Bu, interfeys yenidən qurularkən məlumatların sıfırlanmayacağına zəmanət verir — məsələn, mövzu dəyişdirilərkən və ya ana View yenilənərkən. Apple Developer Documentation (2025) məlumatına görə, @StateObject SwiftUI iyerarxiyasında ObservableObject üçün əsas həqiqət mənbəyi (source of truth) kimi istifadə edilməlidir, uşaq View-lər isə artıq yaradılmış obyekti @ObservedObject və ya @EnvironmentObject vasitəsilə alır.

Əsas məqamlar

  • @StateObject — View daxilində ObservableObject yaratmaq və ona sahib olmaq üçün property wrapper.
  • Bir dəfə yaradılma — obyekt View-in həyatı ərzində bir dəfə inisializasiya edilir və yenidən qurulmalarda təkrar yaranmır.
  • Source of truth — @StateObject iyerarxiyada həqiqət mənbəyidir, @ObservedObject-dən fərqli olaraq.
  • Həyat dövrü — obyekt View yaddaşda olduğu müddətcə yaşayır və onunla birlikdə məhv edilir.
  • İnisializasiya — @StateObject yaradılarkən ilkin dəyər tələb edir, adətən parametrlərlə init vasitəsilə.

SwiftUI-də @StateObject nədir

@StateObject — iOS 14-də təqdim edilmiş property wrapper-dır ki, View-ə ObservableObject protokoluna uyğun sinif nümunəsi yaratmağa və ona sahib olmağa imkan verir. Dəyər tipləri (strukturlar) ilə işləyən @State-dən fərqli olaraq, @StateObject referans tipləri — öz xassələrindəki dəyişikliklər barədə SwiftUI-ə məlumat verə bilən siniflər üçün nəzərdə tutulub.

View @StateObject var viewModel: MyViewModel istifadə etdikdə, SwiftUI View ilk dəfə göstərildikdə avtomatik olaraq MyViewModel nümunəsini yaradır və onu framework-un xüsusi anbarında saxlayır. Hər View yeniləməsində (məsələn, ana vəziyyət dəyişdikdə), SwiftUI obyekti yenidən yaratmır — View iyerarxiyadan silinənə qədər mövcud nümunədən istifadə edir.

Apple WWDC Session 10137 (2024) məlumatına görə, @StateObject iOS 13-də mövcud olan View yenidən qurularkən məlumat itkisi problemini həll edir, o zaman proqramçılar ObservableObject-i ana View-də yaradıb onu inizializator vasitəsilə ötürməli idilər. Bu, kodun təkrarlanmasına və təsadüfi obyektin yenidən yaradılması riskinə səbəb olurdu.

swift
import SwiftUI

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0
    
    func increment() {
        count += 1
    }
}

struct CounterView: View {
    @StateObject var viewModel = CounterViewModel()
    
    var body: some View {
        VStack {
            Text("Say: \(viewModel.count)")
            Button("Artır", action: viewModel.increment)
        }
    }
}

@StateObject necə işləyir

@StateObject mexanizmi SwiftUI-in Combine framework-u ilə inteqrasiyasına əsaslanır. ObservableObject öz xassələrini @Published atributu ilə qeyd etdikdə, SwiftUI avtomatik olaraq ObservableObject protokoluna daxil olan publisher vasitəsilə dəyişikliklərə abunə olur. Dərc edilmiş xassə dəyişdikdə, obyekt objectWillChange publisher vasitəsilə siqnal göndərir, bu da həmin obyekti müşahidə edən bütün View-lərin yenidən çəkilməsini tetikler.

SwiftUI ObservableObject nümunəsini xüsusi View nümunəsinə bağlı anbarda saxlayır. Bu anbar ilk render zamanı bir dəfə yaradılır və View məhv edilənə qədər mövcud olur. Məhz buna görə @StateObject obyektə istinadın sabitliyinə zəmanət verir — SwiftUI yaddaşı avtomatik idarə edir, View inizializatoruna etibar etmir.

objc.io — Thinking in SwiftUI (2025) məlumatına görə, @StateObject-in daxili tətbiqi @State-ə bənzər mexanizmdən istifadə edir, lakin referans tipləri üçün: SwiftUI obyektin ətrafında boxing qabığı yaradır və onun həyat dövrünü tez-tez View iyerarxiyasının yenidən qurulması üçün optimallaşdırılmış öz alokatoru vasitəsilə idarə edir.

@StateObject-in həyat dövrü

  • Yaradılma — View ilk dəfə ekranda görünəndə SwiftUI obyektin inizializatorunu çağırır və istinadı saxlayır.
  • Yenidən qurulma — ana View yeniləndikdə obyekt yenidən yaradılmır, mövcud nümunədən istifadə olunur.
  • Məhv edilmə — View ekranı tərk edib iyerarxiyadan silindikdə, SwiftUI obyektin deinit-ni çağırır.

@StateObject vs @ObservedObject: əsas fərqlər

@StateObject@ObservedObject arasındakı əsas fərq obyektin kimə aid olmasıdır. @StateObject obyekti yaradır və saxlayır — o, sahibdir. @ObservedObject yalnız başqa yerdə yaradılmış və inizializator və ya xassə vasitəsilə ötürülmüş obyekti müşahidə edir.

Xüsusiyyət@StateObject@ObservedObject
SahiplikObyekti yaradır və sahibdirYalnız müşahidə edir
İnisializasiyaView daxilində init/default vasitəsiləXaricdən, parametr vasitəsilə ötürülür
Həyat dövrüView-in həyat dövrünə bağlıdırView tərəfindən idarə olunmur
Yenidən yaratmaYeniləmə zamanı yenidən yaranmırXaricdən əvəz edilə bilər
iOS versiyasıiOS 14+iOS 13+

Qayda sadədir: əgər View ObservableObject-i yaradırsa — @StateObject istifadə edin. Əgər View yalnız valideyndən hazır obyekti alırsa — @ObservedObject istifadə edin. Bu qaydanın pozulması ya məlumat itkisinə (@ObservedObject-in sahiblik üçün istifadəsi), ya da həddindən artıq obyekt yaradılmasına (@StateObject-in müşahidə üçün istifadəsi) gətirib çıxarır.

@StateObject nə vaxt istifadə edilməlidir

@StateObject müəyyən məlumat dəsti üçün həqiqət mənbəyi olan View-lərdə istifadə edilməlidir. Tipik ssenarilərə öz view model-i olan ekranlar, naviqasiya yığınlarının kök ekranları və öz vəziyyətini idarə edən modal təqdimatlar daxildir.

  • View model ilə ekran — öz məlumatları və məntiqi ilə idarə edən hər ekran öz view model-ni @StateObject vasitəsilə yaratmalıdır.
  • Kök View — NavigationStack və ya TabView iyerarxiyasında kök element məlumatları yaradır, uşaq elementlər isə onları @ObservedObject vasitəsilə alır.
  • Modal pəncərələr — .sheet və .fullScreenCover çox vaxt formanı və ya prosesi idarə etmək üçün öz @StateObject tələb edir.
  • Redaktə ilə siyahı — redaktə forması olan siyahının hər sətri öz @StateObject-ə sahib olmalıdır.
swift
struct ProfileView: View {
    @StateObject var viewModel = ProfileViewModel()
    
    var body: some View {
        NavigationStack {
            Form {
                TextField("Name", text: $viewModel.name)
                TextField("Email", text: $viewModel.email)
                Button("Saxla") {
                    viewModel.saveProfile()
                }
            }
            .navigationTitle("Profile")
        }
    }
}

@StateObject-in parametrlərlə inisializasiyası

@StateObject-in parametrlərlə inisializasiyası xüsusi sintaksis tələb edir, çünki SwiftUI obyektin yaradılmasını müstəqil idarə edir. Parametrləri birbaşa inizializatora ötürmək mümkün deyil — escaping closure və ya ayrıca yaratma metodundan istifadə etmək lazımdır.

Swift by Sundell (2024) məlumatına görə, ən təmiz üsul — SwiftUI-in obyekti ilk dəfə yaradarkən çağıracağı fabrik metodu və ya closure istifadə etməkdir. Alternativ yanaşma — ObservableObject-i ana View-də inisializasiya edib standart inizializator vasitəsilə @StateObject-ə ötürməkdir.

swift
class UserViewModel: ObservableObject {
    @Published var user: User
    
    init(user: User) {
        self.user = user
    }
}

struct UserDetailView: View {
    @StateObject var viewModel: UserViewModel
    
    init(user: User) {
        _viewModel = StateObject(wrappedValue: UserViewModel(user: user))
    }
    
    var body: some View {
        Text(viewModel.user.name)
    }
}

Xatırlamaq vacibdir ki, @StateObject ilə View inizializatoru xassə adından əvvəl alt xətt (_viewModel) istifadə etməlidir ki, property wrapper-ın özünə daxil olsun, onun dəyərinə deyil. Bu, inizializatorlarda property wrapper-lərlə işləmək üçün standart Swift nümunəsidir.

@StateObject ilə tipik səhvlər

Ən geniş yayılmış səhv — obyektə sahib olmalı View üçün @ObservedObject-in @StateObject əvəzinə istifadə edilməsidir. Bu halda, valideynin hər yenidən qurulmasında obyekt yenidən yaradılacaq və bütün toplanmış məlumatlar itiriləcək. Bu səhv xüsusilə NavigationStack və ya TabView ilə mürəkkəb iyerarxiyalarda təhlükəlidir.

  • Naviqasiya zamanı məlumat itkisi — uşaq ekran öz view model-i üçün @ObservedObject istifadə edərsə, geri qayıdıb yenidən açdıqda məlumatlar sıfırlanacaq.
  • Yaddaş sızması — heç vaxt silinməyən ana View-də @StateObject yaratmaq, hər uşaq ekran nəzarətsiz @StateObject yaradırsa, obyektlərin yığılmasına səbəb ola bilər.
  • Obyektlərin təkrarlanması — bir ObservableObject-i müxtəlif View-lərdə bir neçə @StateObject-ə ötürmək bir-biri ilə sinxronlaşmayan bir neçə müstəqil nümunə yaradır.

Bu problemlərdən qaçmaq üçün sadə qaydaya əməl edin: bir həqiqət mənbəyi üçün bir @StateObject. Məlumatlar bir neçə ekran arasında paylaşılmalıdırsa — @StateObject-i kök View-də bir dəfə yaradın və uşaq elementlərə @ObservedObject və ya @EnvironmentObject vasitəsilə ötürün.

swift
// ❌ Səhv: @ObservedObject obyektə sahib olmaq üçün
struct BadView: View {
    @ObservedObject var vm = ViewModel() // hər yeniləmədə yenidən yaradılacaq!
}

// ✅ Düzgün: @StateObject sahib olmaq üçün
struct GoodView: View {
    @StateObject var vm = ViewModel() // View-in həyatı üçün bir dəfə yaradıldı
}

Tez-tez verilən suallar

@StateObject və @State arasındakı fərq nədir?

@State dəyər tipləri (strukturlar, sətirlər, rəqəmlər) ilə işləyir və dəyəri birbaşa SwiftUI yaddaşında saxlayır. @StateObject referans tipləri — ObservableObject-ə uyğun siniflər ilə işləyir. @State sadə lokal vəziyyətlər üçün uyğundur, @StateObject isə məntiq və dərc edilmiş xassələri olan mürəkkəb obyektlər üçün.

@StateObject iOS 13-də istifadə edilə bilərmi?

Xeyr, @StateObject yalnız iOS 14 və daha yuxarı versiyalarda mövcuddur. iOS 13 üçün @ObservedObject istifadə edin və ObservableObject-i ana View-də @State vasitəsilə əl ilə həyat dövrü idarəçiliyi ilə yaradın. Alternativ — referans semantikası tələb etməyən məlumatlar üçün class əvəzinə @State ilə struct istifadə etməkdir.

Obyekt valideyndən uşaq View-ə ötürülərsə, @StateObject istifadə etsəm nə olar?

Uşaq View ObservableObject-in öz surətini yaradacaq, valideyndən tamamilə müstəqil. Birindəki dəyişikliklər digərində əks olunmayacaq. Bu, demək olar ki, həmişə səhvdir: valideyndən obyekti almaq üçün @ObservedObject istifadə edin, @StateObject isə yalnız View daxilində yeni obyekt yaratmaq üçün.

@StateObject vasitəsilə yaradılmış obyekt nə vaxt məhv edilir?

Obyekt onu yaradan View SwiftUI iyerarxiyasından tamamilə silindikdə məhv edilir. NavigationStack-dəki ekran üçün bu, naviqasiya yığınından pop zamanı baş verir. Modal pəncərə üçün — bağlandıqda. TabView üçün — View keşlənmirsə, tab dəyişdirilərkən.

İnisializasiya zamanı @StateObject-ə parametrləri necə ötürmək olar?

Alt xətt vasitəsilə property wrapper-a daxil olmaqla xüsusi init istifadə edin: _viewModel = StateObject(wrappedValue: MyViewModel(param: value)). Bu nümunə ObservableObject-ə istənilən parametrləri ötürməyə imkan verir, eyni zamanda View-in həyatı ərzində obyektin bir dəfə yaradılması zəmanətini qoruyur.

Nəticə

  • @StateObject — View daxilində ObservableObject yaratmaq və sahib olmaq üçün property wrapper, iOS 14-dən etibarən mövcuddur.
  • Bir dəfə yaradılma zəmanəti — obyekt bir dəfə inisializasiya edilir və View yenidən qurularkən yenidən yaranmır.
  • Source of truth — @StateObject həqiqət mənbəyidir, @ObservedObject isə yalnız müşahidəçidir.
  • Həyat dövrü — obyekt View SwiftUI iyerarxiyasında olduğu müddətcə yaşayır və onu tərk etdikdə məhv edilir.
  • Parametrlərlə inisializasiya — _viewModel və StateObject(wrappedValue:) vasitəsilə property wrapper-a daxil olmağı tələb edir.
  • Sahiplik səhvi — @ObservedObject-in obyekt yaratmaq üçün istifadəsi yenidən qurulma zamanı məlumat itkisinə səbəb olur.
  • Bir obyekt — bir @StateObject — paylaşılan məlumatlar üçün @StateObject-i kök View-də yaradın və uşaq elementlərə @ObservedObject vasitəsilə ötürün.

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.

Layihəni müzakirə et

Həm də oxuyun