@ObservedObject: шта је то, посматрање објеката и ажурирање View

Аутор: IT Sectr Објављено: 2026-06-26 Време читања: 9 мин

@ObservedObject — је property wrapper у SwiftUI који омогућава View-у да посматра промене у ObservableObject-у креираном на другом месту хијерархије. За разлику од @StateObject, @ObservedObject не креира објекат — он само претплаћује на његов publisher objectWillChange и прецртава View при ажурирању @Published својстава. Ово чини @ObservedObject правим избором за подређена View која добијају податке од родитеља кроз иницијализатор. Према чланку Paul Hudson — Hacking with Swift (2025), типична архитектура SwiftUI апликације се гради овако: корени View користи @StateObject за креирање view model-а, а сва подређена View га добијају кроз @ObservedObject, што обезбеђује јединствени извор истине без дуплирања података.

Главно

  • @ObservedObject — property wrapper за посматрање ObservableObject-а креираног у родитељском View-у.
  • Не поседује објекат — за разлику од @StateObject, @ObservedObject не управља животним циклусом објекта.
  • Претплата на промене — при промени @Published својстава View се аутоматски прецртава.
  • Пренос кроз иницијализатор — објекат се преноси у подређено View кроз параметар иницијализатора.
  • iOS 13+ — @ObservedObject је доступан од прве верзије SwiftUI, за разлику од @StateObject (iOS 14+).

Шта је @ObservedObject у SwiftUI

@ObservedObject — је property wrapper који претплаћује View на промене ObservableObject-а. Када објекат означен са @ObservedObject промени било које од својих својстава декларисаних са @Published, SwiftUI аутоматски прецртава View. @ObservedObject не креира објекат — он само успоставља везу између већ постојеће инстанце ObservableObject-а и View-а које треба да реагује на његове промене.

Кључна разлика између @ObservedObject и @StateObject — је власништво. @ObservedObject претпоставља да је објекат креиран и ускладиштен негде горе у хијерархији View-а. Подређено View добија референцу на овај објекат кроз иницијализатор и једноставно га посматра. Ако подређени View буде поново креиран, добиће исту референцу од родитеља — подаци се не губе.

Према Apple Developer Documentation — SwiftUI (2025), @ObservedObject је доступан од iOS 13, што га чини једином опцијом за посматрање ObservableObject-а у пројектима који подржавају старе верзије iOS-а. У iOS 14+ пожељније је користити @StateObject за креирање објеката, али @ObservedObject остаје актуелан за пренос постојећих објеката.

Како ради @ObservedObject

Механизам @ObservedObject се заснива на протоколу ObservableObject из Combine framework-а. Свака класа која је у складу са ObservableObject аутоматски добија publisher objectWillChange који шаље сигнал пре промене било ког @Published својства. SwiftUI се претплаћује на овај publisher кроз @ObservedObject и по пријему сигнала означава View као да захтева прецртавање.

swift
class TaskViewModel: ObservableObject {
    @Published var tasks: [Task] = []
    @Published var isLoading = false
    
    func loadTasks() async {
        isLoading = true
        // преузми податке
        isLoading = false
    }
}

struct TaskListView: View {
    @ObservedObject var viewModel: TaskViewModel
    
    var body: some View {
        List(viewModel.tasks) { task in
            Text(task.title)
        }
        .task { await viewModel.loadTasks() }
    }
}

Када родитељски View преноси viewModel у TaskListView кроз иницијализатор, SwiftUI креира везу између објекта и View-а. При промени низа tasks или флага isLoading, SwiftUI прецртава TaskListView. Објекат притом остаје непромењен — чува се у родитељском View-у кроз @StateObject.

@ObservedObject vs @StateObject: када шта користити

Разлика између @ObservedObject и @StateObject — је разлика између посматрача и власника. @StateObject креира објекат и управља његовим животним циклусом. @ObservedObject само посматра објекат који је креиран и ускладиштен на другом месту. Избор између њих је одређен одговорношћу View-а за податке.

СценариоПрепорукаРазлог
View креира податке@StateObjectView поседује објекат и одговоран је за његов животни циклус
View добија податке@ObservedObjectView само посматра, објекат живи у родитељу
Подршка за iOS 13@ObservedObject@StateObject недоступан, користите @ObservedObject са ручним управљањем
Компонента за вишекратну употребу@ObservedObjectКомпонента не треба да креира податке — добија их из споља

Главно правило: ако View креира објекат — @StateObject. Ако View прима објекат — @ObservedObject. Кршење овог правила у смеру @ObservedObject за креирање објекта доводи до губитка података при поновној изградњи View-а. Кршење у смеру @StateObject за пријем објекта креира дуплирану инстанцу, независну од родитељске.

Примери коришћења @ObservedObject

Типичан сценариј коришћења @ObservedObject — листа задатака, где корени View креира view model, а ћелија листе га добија кроз @ObservedObject. Свака ћелија може позивати методе view model-а, а промене се аутоматски приказују на целој листи, јер све ћелије посматрају исти објекат.

swift
struct TaskRow: View {
    @ObservedObject var viewModel: TaskViewModel
    let task: Task
    
    var body: some View {
        HStack {
            Text(task.title)
            Spacer()
            Button("Готово") {
                viewModel.completeTask(task)
            }
        }
    }
}

struct TaskListContainer: View {
    @StateObject var viewModel = TaskViewModel()
    
    var body: some View {
        List(viewModel.tasks) { task in
            TaskRow(viewModel: viewModel, task: task)
        }
    }
}

У овом примеру TaskListContainer креира viewModel кроз @StateObject, а свака TaskRow га добија кроз @ObservedObject. Када корисник кликне „Done” у било ком реду, viewModel.completeTask мења published својство, и сви View-ови који посматрају овај објекат се аутоматски ажурирају.

Типичне грешке са @ObservedObject

Најчешћа грешка — коришћење @ObservedObject за креирање објекта унутар View-а. Када се View поново изгради (нпр. при промени state-а), SwiftUI креира нову инстанцу ObservableObject-а, што доводи до губитка свих прикупљених података. Ова грешка је посебно болна у NavigationStack-у, где корисник може попунити формулар и изгубити податке при повратку назад.

Грешка: @ObservedObject уместо @StateObject

swift
// ❌ Губитак података: @ObservedObject не задржава објекат
struct FormView: View {
    @ObservedObject var formVM = FormViewModel()
    // Нови formVM се креира при свакој поновној изградњи View-а!
}

// ✅ Исправно: @StateObject задржава објекат
struct FormView: View {
    @StateObject var formVM = FormViewModel()
    // Објекат креиран једном током живота View-а
}

Грешка: пренос @StateObject тамо где је потребан @ObservedObject

Ако подређено View декларише исти ObservableObject кроз @StateObject, креира независну копију. Промене у родитељском објекту неће бити видљиве у подређеном и обрнуто. Увек користите @ObservedObject за подређена View која добијају објекат из споља.

Алтернативе за @ObservedObject у SwiftUI

У савременом SwiftUI постоји неколико алтернатива за @ObservedObject, свака са својим предностима. Избор зависи од архитектуре апликације, верзије iOS-а и конкретног сценарија коришћења.

  • @EnvironmentObject — омогућава добијање објекта из окружења SwiftUI без експлицитног преноса кроз иницијализатор. Погодан за објекте потребне на многим екранима, али захтева експлицитно убацивање кроз .environmentObject().
  • @State + @Binding — за једноставне типове вредности нису потребни ObservableObject. Користите @State за чување и @Binding за пренос у подређена View.
  • @AppStorage — за UserDefaults вредности које треба да се аутоматски синхронизују са View-ом.
  • @SceneStorage — за чување привременог стања између поновних покретања сцене (нпр. позиција у листи).

Избор између @ObservedObject и @EnvironmentObject — је питање стила и архитектуре. @ObservedObject експлицитно показује зависности View-а кроз иницијализатор, што чини код предвидљивијим. @EnvironmentObject је погодан за дубоке хијерархије, али скрива зависности, што може отежати отклањање грешака.

Често постављана питања

Може ли се користити @ObservedObject без @StateObject у родитељу?

Да, ако се објекат креира и чува ван SwiftUI — на пример, у AppDelegate или синглтону. У овом случају @ObservedObject се једноставно претплаћује на промене постојећег објекта. Међутим, за објекте креиране унутар SwiftUI хијерархије увек је потребан @StateObject негде изнад.

Зашто @ObservedObject понекад не ажурира View?

Највероватнији разлог — својство се мења не кроз @Published или се не мења сам објекат, већ његова унутрашња структура без позивања objectWillChange. За колекције користите доделу нове копије: array.append() није довољно — потребно је поново доделити цео низ кроз array = array + [element].

Да ли @ObservedObject утиче на перформансе?

@ObservedObject сам по себи не ствара значајно оптерећење. Проблеми настају при честим променама @Published својстава — свака промена покреће прецртавање свих посматрачких View-ова. За оптимизацију користите EquatableView, смањите број published својстава и избегавајте непотребна ажурирања.

По чему се @ObservedObject разликује од @Binding?

@ObservedObject посматра целу класу ObservableObject и прецртава View при свакој промени његових published својстава. @Binding креира двосмерну везу са одређеном вредношћу (String, Int, Bool) и омогућава читање и писање исте. @Binding је лакши и не захтева ObservableObject.

Може ли се комбиновати @ObservedObject са @Published у истој класи?

Да, то је стандардни образац. @Published унутар ObservableObject-а се аутоматски интегрише са @ObservedObject. Свако @Published својство додаје посматрача publisher-у objectWillChange. При промени било ког од њих, сви View-ови са @ObservedObject за овај објекат се прецртавају.

Резиме

  • @ObservedObject — property wrapper за посматрање ObservableObject-а креираног на другом месту хијерархије.
  • Не поседује објекат — за разлику од @StateObject, @ObservedObject не управља животним циклусом и не креира објекат.
  • Претплата кроз Combine — SwiftUI се аутоматски претплаћује на publisher objectWillChange ObservableObject-а.
  • iOS 13+ — @ObservedObject је доступан од прве верзије SwiftUI, што је важно за пројекте са старом подршком.
  • Пренос кроз иницијализатор — објекат се експлицитно преноси у подређено View, чинећи зависности транспарентним.
  • Грешка власништва — коришћење @ObservedObject за креирање објекта доводи до губитка података при поновној изградњи View-а.
  • Алтернативе — @EnvironmentObject за убацивање кроз окружење, @State/@Binding за типове вредности.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође