@StateObject је property wrapper у SwiftUI-ју који креира и поседује инстанцу ObservableObject током целог животног циклуса View-а. Када се View први пут појави на екрану, @StateObject иницијализује објекат и чува га док View не буде уклоњено из меморије. Ово гарантује да се подаци неће ресетовати приликом поновне изградње интерфејса — на пример, при промени теме или ажурирању родитељског View-а. Према Apple Developer Documentation (2025), @StateObject треба користити као главни извор истине (source of truth) за ObservableObject у хијерархији SwiftUI-ја, док подређена View добијају већ креирани објекат путем @ObservedObject или @EnvironmentObject.
Главне тачке
@StateObject је property wrapper представљен у iOS 14 који омогућава View-у да креира и поседује инстанцу класе која је у складу са протоколом ObservableObject. За разлику од @State-а који ради са вредносним типовима (структурама), @StateObject је намењен референтним типовима — класама које могу обавештавати SwiftUI о променама својих својстава.
Када View користи @StateObject var viewModel: MyViewModel, SwiftUI аутоматски креира инстанцу MyViewModel при првом приказивању View-а и чува је у посебном складишту оквира. При сваком ажурирању View-а (на пример, при промени родитељског стања), SwiftUI не поново ствара објекат — користи постојећу инстанцу док View не буде уклоњено из хијерархије.
Према Apple WWDC Session 10137 (2024), @StateObject решава проблем губитка података при поновној изградњи View-а који је постојао у iOS 13, када су програмери морали да креирају ObservableObject у родитељском View-у и прослеђују га кроз иницијализатор. То је доводило до дуплирања кода и ризика од случајног поновног стварања објекта.
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("Број: \(viewModel.count)")
Button("Увећај", action: viewModel.increment)
}
}
}
Механизам @StateObject се заснива на интеграцији SwiftUI-ја са Combine оквиром. Када ObservableObject означи своја својства атрибутом @Published, SwiftUI се аутоматски претплаћује на промене путем publisher-а уграђеног у протокол ObservableObject. При промени објављеног својства, објекат шаље сигнал путем objectWillChange publisher-а, што покреће поновно цртање свих View-а која посматрају овај објекат.
SwiftUI чува инстанцу ObservableObject у посебном складишту везаном за одређену инстанцу View-а. Ово складиште се креира једном при првом рендеровању и постоји до уништења View-а. Управо зато @StateObject гарантује стабилност референце на објекат — SwiftUI аутоматски управља меморијом, не ослањајући се на иницијализатор View-а.
Према objc.io — Thinking in SwiftUI (2025), унутрашња имплементација @StateObject користи механизам сличан @State-у, али за референтне типове: SwiftUI креира boxing омотач око објекта и управља његовим животним циклусом путем сопственог алокатора, оптимизованог за честе преправке хијерархије View-а.
Главна разлика између @StateObject и @ObservedObject је у томе ко поседује објекат. @StateObject креира и чува објекат — он је власник. @ObservedObject само посматра објекат који је креиран негде другде и прослеђен кроз иницијализатор или својство.
| Карактеристика | @StateObject | @ObservedObject |
|---|---|---|
| Власништво | Креира и поседује објекат | Само посматра |
| Иницијализација | Унутар View-а путем init/default | Споља, прослеђује се кроз параметар |
| Животни циклус | Везан за животни циклус View-а | Није контролисан од стране View-а |
| Поновно стварање | Не ствара се поново при ажурирању | Може бити замењен споља |
| iOS верзија | iOS 14+ | iOS 13+ |
Правило је једноставно: ако View креира ObservableObject — користи @StateObject. Ако View само прима већ готов објекат од родитеља — користи @ObservedObject. Кршење овог правила доводи или до губитка података (ако користите @ObservedObject за поседовање), или до прекомерног креирања објеката (ако користите @StateObject за посматрање).
@StateObject треба користити у оним View-има која су извор истине за одређени скуп података. Типични сценарији укључују екране са сопственим view model-ом, коренске екране навигационих стекова и модалне презентације које управљају сопственим стањем.
struct ProfileView: View {
@StateObject var viewModel = ProfileViewModel()
var body: some View {
NavigationStack {
Form {
TextField("Name", text: $viewModel.name)
TextField("Email", text: $viewModel.email)
Button("Сачувај") {
viewModel.saveProfile()
}
}
.navigationTitle("Profile")
}
}
}
Иницијализација @StateObject са параметрима захтева употребу посебне синтаксе, јер SwiftUI самостално управља креирањем објекта. Не можете једноставно проследити параметре у иницијализатор — потребно је користити escaping затварање или посебан метод креирања.
Према Swift by Sundell (2024), најчистији начин је коришћење фабричког метода или затварања које ће SwiftUI позвати при првом креирању објекта. Алтернативни приступ — иницијализовати ObservableObject у родитељском View-у и проследити га путем @StateObject користећи стандардни иницијализатор.
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)
}
}
Важно је запамтити да иницијализатор View-а са @StateObject мора користити доњу црту испред имена својства (_viewModel) за приступ самом property wrapper-у, а не његовој вредности. Ово је стандардни Swift образац за рад са property wrapper-има у иницијализаторима.
Најчешћа грешка је коришћење @ObservedObject уместо @StateObject за View које треба да поседује објекат. У овом случају, при свакој преправци родитеља, објекат ће бити поново креиран, што доводи до губитка свих прикупљених података. Ова грешка је посебно подмукла у сложеним хијерархијама са NavigationStack или TabView.
Да бисте избегли ове проблеме, следите једноставно правило: један @StateObject по једном извору истине. Ако подаци треба да буду заједнички за више екрана — креирајте @StateObject једном у коренском View-у и прослеђујте га путем @ObservedObject или @EnvironmentObject подређеним елементима.
// ❌ Погрешно: @ObservedObject за поседовање објекта
struct BadView: View {
@ObservedObject var vm = ViewModel() // биће поново креиран при сваком ажурирању!
}
// ✅ Исправно: @StateObject за поседовање
struct GoodView: View {
@StateObject var vm = ViewModel() // креиран једном за животни век View-а
}
Често постављана питања
@State ради са вредносним типовима (структуре, стрингови, бројеви) и чува вредност директно у SwiftUI складишту. @StateObject ради са референтним типовима — класама у складу са ObservableObject. @State је погодан за једноставна локална стања, @StateObject — за сложене објекте са логиком и објављеним својствима.
Не, @StateObject је доступан само од iOS 14 и новије. За iOS 13 користите @ObservedObject и креирајте ObservableObject у родитељском View-у путем @State са ручним управљањем животним циклусом. Алтернатива — користите @State са struct уместо class за податке који не захтевају референтну семантику.
Подређени View ће креирати своју сопствену копију ObservableObject-а, потпуно независну од родитељске. Промене у једној неће се одразити на другу. Ово је готово увек грешка: користите @ObservedObject за пријем објекта од родитеља, а @StateObject само за креирање новог објекта унутар View-а.
Објекат се уништава када View које га је креирало буде потпуно уклоњено из SwiftUI хијерархије. За екран у NavigationStack-у то се дешава при pop-у са навигационог стека. За модални прозор — при његовом затварању. За TabView — при пребацивању картице, ако View није кеширано.
Користите прилагођени init са приступом property wrapper-у кроз доњу црту: _viewModel = StateObject(wrappedValue: MyViewModel(param: value)). Овај образац омогућава прослеђивање било којих параметара ObservableObject-у, задржавајући притом гаранцију јединственог креирања објекта током живота View-а.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође