@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 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.
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.
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.
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.
| Scenario | Rekomendasyon | Dahilan |
|---|---|---|
| View lumilikha ng data | @StateObject | View nagmamay-ari ng bagay at responsable para sa lifecycle nito |
| View tumatanggap ng data | @ObservedObject | View 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 | @ObservedObject | Component 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.
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.
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.
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.
// ❌ 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
}
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.
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.
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
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.
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].
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.
@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.
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
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.
Basahin din