@ObservedObject: ano ito, pagmamasid ng mga bagay at pag-update ng View

May-akda: IT Sectr Nai-publish: 2026-06-26 Oras ng pagbabasa: 9 min

@ObservedObject ay isang property wrapper sa SwiftUI na nagpapahintulot sa View na masdan ang mga pagbabago sa ObservableObject na ginawa sa ibang lugar ng hierarchy. Hindi tulad ng @StateObject, ang @ObservedObject ay hindi lumilikha ng bagay — ito ay nagse-subscribe lamang sa publisher nitong objectWillChange at muling iginuguhit ang View kapag na-update ang mga @Published na property. Ginagawa nitong tamang pagpili ang @ObservedObject para sa mga anak na View na tumatanggap ng data mula sa magulang sa pamamagitan ng initializer. Ayon sa artikulo ni Paul Hudson — Hacking with Swift (2025), ang tipikal na arkitektura ng SwiftUI application ay binuo ng ganito: ang root View ay gumagamit ng @StateObject para lumikha ng view model, at lahat ng anak na View ay tumatanggap nito sa pamamagitan ng @ObservedObject, na nagbibigay ng iisang source ng katotohanan nang walang pagdodoble ng data.

Mga Pangunahing Punto

  • @ObservedObject — property wrapper para sa pagmamasid ng ObservableObject na ginawa sa magulang na View.
  • Hindi nagmamay-ari ng bagay — hindi tulad ng @StateObject, ang @ObservedObject ay hindi namamahala ng lifecycle ng bagay.
  • Subscription sa mga pagbabago — kapag nagbago ang @Published na property, awtomatikong muling iginuguhit ang View.
  • Pagpapasa sa pamamagitan ng initializer — ang bagay ay ipinapasa sa anak na View sa pamamagitan ng parameter ng initializer.
  • iOS 13+ — ang @ObservedObject ay available mula sa unang bersyon ng SwiftUI, hindi tulad ng @StateObject (iOS 14+).

Ano ang @ObservedObject sa SwiftUI

@ObservedObject ay isang property wrapper na nagse-subscribe ng View sa mga pagbabago ng ObservableObject. Kapag ang bagay na may markang @ObservedObject ay nagbago ng alinman sa mga property nitong idineklara gamit ang @Published, awtomatikong muling iginuguhit ng SwiftUI ang View. Ang @ObservedObject ay hindi lumilikha ng bagay — ito ay nagtatatag lamang ng koneksyon sa pagitan ng umiiral nang instance ng ObservableObject at ng View na dapat tumugon sa mga pagbabago nito.

Ang pangunahing pagkakaiba sa pagitan ng @ObservedObject at @StateObject — ay pagmamay-ari. Ipinapalagay ng @ObservedObject na ang bagay ay ginawa at iniimbak sa isang lugar na mas mataas sa hierarchy ng View. Ang anak na View ay tumatanggap ng reference sa bagay na ito sa pamamagitan ng initializer at sinusunod lamang ito. Kung ang anak na View ay muling nilikha, matatanggap nito ang parehong reference mula sa magulang — hindi mawawala ang data.

Ayon sa Apple Developer Documentation — SwiftUI (2025), ang @ObservedObject ay available mula sa iOS 13, na ginagawa itong tanging opsyon para sa pagmamasid ng ObservableObject sa mga proyektong sumusuporta sa lumang bersyon ng iOS. Sa iOS 14+, ang @StateObject ay mas gusto para sa paglikha ng mga bagay, ngunit ang @ObservedObject ay nananatiling may kaugnayan para sa pagpapasa ng mga umiiral nang bagay.

Paano gumagana ang @ObservedObject

Ang mekanismo ng @ObservedObject ay batay sa ObservableObject protocol mula sa Combine framework. Ang bawat klase na sumusunod sa ObservableObject ay awtomatikong nakakakuha ng publisher objectWillChange na nagpapadala ng signal bago ang pagbabago ng anumang @Published na property. Ang SwiftUI ay nagse-subscribe sa publisher na ito sa pamamagitan ng @ObservedObject at pagkatanggap ng signal, minamarkahan ang View bilang nangangailangan ng muling pagguhit.

swift
class TaskViewModel: ObservableObject {
    @Published var tasks: [Task] = []
    @Published var isLoading = false
    
    func loadTasks() async {
        isLoading = true
        // kunin ang data
        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() }
    }
}

Kapag ang magulang na View ay nagpapasa ng viewModel sa TaskListView sa pamamagitan ng initializer, lumilikha ang SwiftUI ng koneksyon sa pagitan ng bagay at ng View. Kapag nagbago ang array ng tasks o ang isLoading flag, muling iginuguhit ng SwiftUI ang TaskListView. Ang bagay ay nananatiling hindi nagbabago — ito ay iniimbak sa magulang na View sa pamamagitan ng @StateObject.

@ObservedObject vs @StateObject: kailan gagamitin ang ano

Ang pagkakaiba sa pagitan ng @ObservedObject at @StateObject — ay ang pagkakaiba sa pagitan ng tagamasid at may-ari. Ang @StateObject ay lumilikha ng bagay at namamahala ng lifecycle nito. Ang @ObservedObject ay tumitingin lamang sa bagay na ginawa at iniimbak sa ibang lugar. Ang pagpili sa pagitan ng mga ito ay tinutukoy ng responsibilidad ng View para sa data.

ScenarioRekomendasyonDahilan
View lumilikha ng data@StateObjectView nagmamay-ari ng bagay at responsable para sa lifecycle nito
View tumatanggap ng data@ObservedObjectView tumitingin lamang, bagay ay nabubuhay sa magulang
Suporta sa iOS 13@ObservedObject@StateObject hindi available, gamitin ang @ObservedObject na may manual na pamamahala
Component na magagamit muli@ObservedObjectComponent ay hindi dapat lumikha ng data — ito ay tumatanggap mula sa labas

Pangunahing patakaran: kung ang View ay lumilikha ng bagay — @StateObject. Kung ang View ay tumatanggap ng bagay — @ObservedObject. Ang paglabag sa patakarang ito pabor sa @ObservedObject para sa paglikha ng bagay ay humahantong sa pagkawala ng data kapag muling itinayo ang View. Ang paglabag pabor sa @StateObject para sa pagtanggap ng bagay ay lumilikha ng duplicate na instance, independiyente sa magulang.

Mga halimbawa ng paggamit ng @ObservedObject

Ang tipikal na scenario ng paggamit ng @ObservedObject — isang listahan ng mga gawain, kung saan ang root View ay lumilikha ng view model, at ang cell ng listahan ay tumatanggap nito sa pamamagitan ng @ObservedObject. Ang bawat cell ay maaaring tumawag ng mga method ng view model, at ang mga pagbabago ay awtomatikong ipinapakita sa buong listahan, dahil ang lahat ng cell ay tumitingin sa parehong bagay.

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

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

Sa halimbawang ito, ang TaskListContainer ay lumilikha ng viewModel sa pamamagitan ng @StateObject, at bawat TaskRow ay tumatanggap nito sa pamamagitan ng @ObservedObject. Kapag ang user ay nag-click ng “Done” sa anumang row, binabago ng viewModel.completeTask ang published na property, at lahat ng View na tumitingin sa bagay na ito ay awtomatikong naa-update.

Mga karaniwang pagkakamali sa @ObservedObject

Ang pinakakaraniwang pagkakamali — paggamit ng @ObservedObject para lumikha ng bagay sa loob ng View. Kapag ang View ay muling itinayo (halimbawa, kapag nagbago ang state), lumilikha ang SwiftUI ng bagong instance ng ObservableObject, na humahantong sa pagkawala ng lahat ng nakalap na data. Ang pagkakamaling ito ay lalong masakit sa NavigationStack, kung saan ang user ay maaaring mag-fill out ng form at mawalan ng data kapag bumalik.

Pagkakamali: @ObservedObject sa halip na @StateObject

swift
// ❌ Pagkawala ng data: Hindi pinapanatili ng @ObservedObject ang bagay
struct FormView: View {
    @ObservedObject var formVM = FormViewModel()
    // Bagong formVM na ginagawa sa bawat muling pagtatayo ng View!
}

// ✅ Tama: Pinapanatili ng @StateObject ang bagay
struct FormView: View {
    @StateObject var formVM = FormViewModel()
    // Bagay na ginawa nang isang beses sa buhay ng View
}

Pagkakamali: pagpapasa ng @StateObject kung saan kailangan ang @ObservedObject

Kung ang anak na View ay nagdeklara ng parehong ObservableObject sa pamamagitan ng @StateObject, lumilikha ito ng independiyenteng kopya. Ang mga pagbabago sa magulang na bagay ay hindi makikita sa anak at vice versa. Palaging gamitin ang @ObservedObject para sa mga anak na View na tumatanggap ng bagay mula sa labas.

Mga alternatibo sa @ObservedObject sa SwiftUI

Sa modernong SwiftUI, may ilang alternatibo sa @ObservedObject, bawat isa ay may kanya-kanyang pakinabang. Ang pagpili ay depende sa arkitektura ng application, bersyon ng iOS, at partikular na scenario ng paggamit.

  • @EnvironmentObject — nagpapahintulot na makuha ang bagay mula sa kapaligiran ng SwiftUI nang walang eksplisitong pagpapasa sa pamamagitan ng initializer. Maginhawa para sa mga bagay na kailangan sa maraming screen, ngunit nangangailangan ng eksplisitong injection sa pamamagitan ng .environmentObject().
  • @State + @Binding — para sa mga simpleng value type ay hindi kailangan ng ObservableObject. Gamitin ang @State para sa pag-iimbak at @Binding para sa pagpapasa sa mga anak na View.
  • @AppStorage — para sa mga UserDefaults value na dapat awtomatikong mag-sync sa View.
  • @SceneStorage — para sa pag-iimbak ng pansamantalang estado sa pagitan ng mga restart ng scene (halimbawa, posisyon sa listahan).

Ang pagpili sa pagitan ng @ObservedObject at @EnvironmentObject — ay isang bagay ng estilo at arkitektura. Ang @ObservedObject ay eksplisitong nagpapakita ng mga dependence ng View sa pamamagitan ng initializer, na ginagawang mas predictable ang code. Ang @EnvironmentObject ay maginhawa para sa malalim na hierarchies, ngunit itinatago ang mga dependence, na maaaring magpahirap sa debugging.

Mga Madalas Itanong

Maaari bang gamitin ang @ObservedObject nang walang @StateObject sa magulang?

Oo, kung ang bagay ay ginawa at iniimbak sa labas ng SwiftUI — halimbawa, sa AppDelegate o singleton. Sa kasong ito, ang @ObservedObject ay nagse-subscribe lamang sa mga pagbabago ng umiiral nang bagay. Gayunpaman, para sa mga bagay na ginawa sa loob ng SwiftUI hierarchy, palaging kailangan ang @StateObject sa isang lugar sa itaas.

Bakit minsan hindi ina-update ng @ObservedObject ang View?

Ang pinaka-malamang na dahilan — ang property ay binabago hindi sa pamamagitan ng @Published o hindi ang bagay mismo ang nagbabago, kundi ang panloob na istraktura nito nang hindi tumatawag ng objectWillChange. Para sa mga koleksyon, gumamit ng pagtatalaga ng bagong kopya: array.append() ay hindi sapat — kailangang italaga muli ang buong array sa pamamagitan ng array = array + [element].

Nakakaapekto ba ang @ObservedObject sa performance?

Ang @ObservedObject mismo ay hindi lumilikha ng makabuluhang load. Ang mga problema ay lumilitaw sa madalas na pagbabago ng @Published na mga property — bawat pagbabago ay nagti-trigger ng muling pagguhit ng lahat ng tumitingin na View. Para sa optimization, gamitin ang EquatableView, bawasan ang bilang ng mga published na property at iwasan ang mga hindi kinakailangang update.

Ano ang pagkakaiba ng @ObservedObject sa @Binding?

@ObservedObject ay tumitingin sa buong ObservableObject class at muling iginuguhit ang View sa bawat pagbabago ng mga published na property nito. @Binding ay lumilikha ng two-way na koneksyon sa isang partikular na value (String, Int, Bool) at nagpapahintulot na basahin at isulat ito. Ang @Binding ay mas magaan at hindi nangangailangan ng ObservableObject.

Maaari bang pagsamahin ang @ObservedObject at @Published sa iisang klase?

Oo, ito ay isang karaniwang pattern. Ang @Published sa loob ng ObservableObject ay awtomatikong nag-i-integrate sa @ObservedObject. Bawat @Published na property ay nagdaragdag ng tagamasid sa objectWillChange publisher. Kapag nagbago ang alinman sa kanila, lahat ng View na may @ObservedObject para sa bagay na ito ay muling iginuguhit.

Buod

  • @ObservedObject — property wrapper para sa pagmamasid ng ObservableObject na ginawa sa ibang lugar ng hierarchy.
  • Hindi nagmamay-ari ng bagay — hindi tulad ng @StateObject, ang @ObservedObject ay hindi namamahala ng lifecycle at hindi lumilikha ng bagay.
  • Subscription sa pamamagitan ng Combine — ang SwiftUI ay awtomatikong nagse-subscribe sa objectWillChange publisher ng ObservableObject.
  • iOS 13+ — ang @ObservedObject ay available mula sa unang bersyon ng SwiftUI, mahalaga para sa mga proyektong may lumang suporta.
  • Pagpapasa sa pamamagitan ng initializer — ang bagay ay eksplisitong ipinapasa sa anak na View, ginagawang transparent ang mga dependence.
  • Pagkakamali sa pagmamay-ari — paggamit ng @ObservedObject para lumikha ng bagay ay humahantong sa pagkawala ng data kapag muling itinayo ang View.
  • Mga alternatibo — @EnvironmentObject para sa injection sa pamamagitan ng kapaligiran, @State/@Binding para sa value types.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din