@StateObject — SwiftUI dagi property wrapper bo'lib, View ning butun hayot sikl davomida ObservableObject nusxasini yaratadi va unga egalik qiladi. View birinchi marta ekranda paydo bo'lganda, @StateObject obyektni inicializatsiya qiladi va View xotiradan o'chirilgunga qadar uni saqlaydi. Bu interfeys qayta qurilganda ma'lumotlarning tiklanmasligini kafolatlaydi — masalan, mavzu o'zgartirilganda yoki ota View yangilanganda. Apple Developer Documentation (2025) ga ko'ra, @StateObject SwiftUI iyerarxiyasida ObservableObject uchun asosiy haqiqat manbai (source of truth) sifatida ishlatilishi kerak, bola View lar esa yaratilgan obyektni @ObservedObject yoki @EnvironmentObject orqali oladi.
Asosiy fikrlar
@StateObject — iOS 14 da taqdim etilgan property wrapper bo'lib, View ga ObservableObject protokoliga mos keladigan sinf nusxasini yaratish va unga egalik qilish imkonini beradi. Qiymat turlari (strukturalar) bilan ishlaydigan @State dan farqli o'laroq, @StateObject mos yozuvlar turlari — SwiftUI ni o'z xususiyatlaridagi o'zgarishlar haqida xabardor qila oladigan sinflar uchun mo'ljallangan.
View @StateObject var viewModel: MyViewModel dan foydalanganda, SwiftUI View birinchi marta ko'rsatilganda avtomatik ravishda MyViewModel nusxasini yaratadi va uni framework ning maxsus omborida saqlaydi. Har bir View yangilanishida (masalan, ota holati o'zgarganda), SwiftUI obyektni qayta yaratmaydi — View iyerarxiyadan o'chirilgunga qadar mavjud nusxadan foydalanadi.
Apple WWDC Session 10137 (2024) ma'lumotiga ko'ra, @StateObject iOS 13 da mavjud bo'lgan View qayta qurilganda ma'lumot yo'qotish muammosini hal qiladi, o'shanda dasturchilar ObservableObject ni ota View da yaratib, uni inicializator orqali uzatishlari kerak edi. Bu kod takrorlanishiga va tasodifiy obyekt qayta yaratilish xavfiga olib kelardi.
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("Sanoq: \(viewModel.count)")
Button("Oshirish", action: viewModel.increment)
}
}
}
@StateObject mexanizmi SwiftUI ning Combine framework bilan integratsiyasiga asoslanadi. ObservableObject o'z xususiyatlarini @Published atributi bilan belgilaganda, SwiftUI avtomatik ravishda ObservableObject protokoliga o'rnatilgan publisher orqali o'zgarishlarga obuna bo'ladi. Nashr qilingan xususiyat o'zgarganda, obyekt objectWillChange publisher orqali signal yuboradi, bu esa ushbu obyektni kuzatayotgan barcha View larning qayta chizilishini tetiklaydi.
SwiftUI ObservableObject nusxasini ma'lum View nusxasiga bog'langan maxsus omborda saqlaydi. Bu ombor birinchi renderda bir marta yaratiladi va View yo'q qilinguncha mavjud bo'ladi. Aynan shuning uchun @StateObject obyektga havolaning barqarorligini kafolatlaydi — SwiftUI xotirani avtomatik boshqaradi, View inicializatoriga tayanmaydi.
objc.io — Thinking in SwiftUI (2025) ma'lumotiga ko'ra, @StateObject ning ichki tatbiqi @State ga o'xshash mexanizmdan foydalanadi, lekin mos yozuvlar turlari uchun: SwiftUI obyekt atrofida boxing qobig'ini yaratadi va uning hayot siklini tez-tez View iyerarxiyasini qayta qurish uchun optimallashtirilgan o'z alokatori orqali boshqaradi.
@StateObject va @ObservedObject o'rtasidagi asosiy farq obyekt kimga tegishli ekanligidadir. @StateObject obyektni yaratadi va saqlaydi — u egasidir. @ObservedObject faqat boshqa joyda yaratilgan va inicializator yoki xususiyat orqali uzatilgan obyektni kuzatadi.
| Xususiyat | @StateObject | @ObservedObject |
|---|---|---|
| Egalik | Obyektni yaratadi va egalik qiladi | Faqat kuzatadi |
| Inicializatsiya | View ichida init/default orqali | Tashqaridan, parametr orqali uzatiladi |
| Hayot sikl | View hayot siklga bog'liq | View tomonidan boshqarilmaydi |
| Qayta yaratish | Yangilanishda qayta yaratilmaydi | Tashqaridan almashtirilishi mumkin |
| iOS versiyasi | iOS 14+ | iOS 13+ |
Qoida oddiy: agar View ObservableObject ni yaratayotgan bo'lsa — @StateObject dan foydalaning. Agar View faqat ota dan tayyor obyektni olayotgan bo'lsa — @ObservedObject dan foydalaning. Ushbu qoidaning buzilishi yoki ma'lumot yo'qotilishiga (@ObservedObject ni egalik uchun ishlatish) yoki ortiqcha obyekt yaratilishiga (@StateObject ni kuzatish uchun ishlatish) olib keladi.
@StateObject ma'lum ma'lumotlar to'plami uchun haqiqat manbai bo'lgan View larda ishlatilishi kerak. Odatdagi stsenariylarga o'z view model iga ega ekranlar, navigatsiya steklarining ildiz ekranlari va o'z holatini boshqaradigan modal taqdimotlar kiradi.
struct ProfileView: View {
@StateObject var viewModel = ProfileViewModel()
var body: some View {
NavigationStack {
Form {
TextField("Name", text: $viewModel.name)
TextField("Email", text: $viewModel.email)
Button("Saqlash") {
viewModel.saveProfile()
}
}
.navigationTitle("Profile")
}
}
}
@StateObject ni parametrlar bilan inicializatsiya qilish maxsus sintaksis talab qiladi, chunki SwiftUI obyekt yaratilishini mustaqil boshqaradi. Parametrlarni to'g'ridan-to'g'ri inicializatorga uzatib bo'lmaydi — escaping closure yoki alohida yaratish metodidan foydalanish kerak.
Swift by Sundell (2024) ma'lumotiga ko'ra, eng toza usul — SwiftUI obyektni birinchi marta yaratishda chaqiradigan fabrika metodi yoki closure dan foydalanishdir. Muqobil yondashuv — ObservableObject ni ota View da inicializatsiya qilib, uni standart inicializator orqali @StateObject ga uzatish.
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)
}
}
Shuni yodda tutish kerakki, @StateObject bilan View inicializatori xususiyat nomidan oldin pastki chiziq (_viewModel) ishlatishi kerak, bu property wrapper ning o'ziga kirish uchun, uning qiymatiga emas. Bu inicializatorlarda property wrapper lar bilan ishlash uchun standart Swift namunasidir.
Eng keng tarqalgan xato — obyektga ega bo'lishi kerak bo'lgan View uchun @ObservedObject ni @StateObject o'rniga ishlatishdir. Bu holda, ota ning har bir qayta qurilishida obyekt qayta yaratiladi, bu esa barcha to'plangan ma'lumotlarning yo'qolishiga olib keladi. Bu xato ayniqsa NavigationStack yoki TabView bilan murakkab iyerarxiyalarda xavflidir.
Bu muammolardan qochish uchun oddiy qoidaga amal qiling: bitta haqiqat manbai uchun bitta @StateObject. Agar ma'lumotlar bir nechta ekran o'rtasida taqsimlanishi kerak bo'lsa — @StateObject ni ildiz View da bir marta yarating va bola elementlarga @ObservedObject yoki @EnvironmentObject orqali uzating.
// ❌ Noto'g'ri: @ObservedObject obyektga egalik qilish uchun
struct BadView: View {
@ObservedObject var vm = ViewModel() // har bir yangilanishda qayta yaratiladi!
}
// ✅ To'g'ri: @StateObject egalik qilish uchun
struct GoodView: View {
@StateObject var vm = ViewModel() // View hayoti uchun bir marta yaratilgan
}
Tez-tez beriladigan savollar
@State qiymat turlari (strukturalar, satrlar, raqamlar) bilan ishlaydi va qiymatni to'g'ridan-to'g'ri SwiftUI xotirasida saqlaydi. @StateObject mos yozuvlar turlari — ObservableObject ga mos keladigan sinflar bilan ishlaydi. @State oddiy lokal holatlar uchun mos, @StateObject esa mantiq va nashr qilingan xususiyatlarga ega murakkab obyektlar uchun.
Yo'q, @StateObject faqat iOS 14 va undan yuqori versiyalarda mavjud. iOS 13 uchun @ObservedObject dan foydalaning va ObservableObject ni ota View da @State orqali qo'lda hayot sikl boshqaruvi bilan yarating. Muqobil — mos yozuvlar semantikasini talab qilmaydigan ma'lumotlar uchun class o'rniga @State bilan struct ishlatish.
Bola View ObservableObject ning o'z nusxasini yaratadi, otadan butunlay mustaqil. Biridagi o'zgarishlar ikkinchisida aks etmaydi. Bu deyarli har doim xato: otadan obyektni olish uchun @ObservedObject ishlating, @StateObject ni faqat View ichida yangi obyekt yaratish uchun.
Obyekt uni yaratgan View SwiftUI iyerarxiyasidan butunlay o'chirilganda yo'q qilinadi. NavigationStack dagi ekran uchun bu navigatsiya stekidan pop paytida sodir bo'ladi. Modal oyna uchun — yopilganda. TabView uchun — View keshlanmasa, tab o'zgartirilganda.
Pastki chiziq orqali property wrapper ga kirish bilan maxsus init dan foydalaning: _viewModel = StateObject(wrappedValue: MyViewModel(param: value)). Bu namuna ObservableObject ga istalgan parametrlarni uzatish imkonini beradi, shu bilan birga View hayoti davomida obyektning bir marta yaratilishi kafolatini saqlaydi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.