Ang @ObservedObject ay isang Property Wrapper sa SwiftUI para sa pagmamasid ng isang instance ng ObservableObject na ipinasa mula sa labas. Hindi tulad ng @StateObject, ang @ObservedObject ay hindi gumagawa ng bagay — ito ay nag-subscribe sa mga pagbabago ng isang umiiral na. Ayon sa Apple Developer Documentation (2025), ang @ObservedObject ay ginagamit sa mga child view na kailangang subaybayan ang data na pagmamay-ari ng parent. @ObservedObject ay nagbibigay ng reaktibong koneksyon nang hindi pinangangasiwaan ang lifecycle ng bagay.
Mga Pangunahing
@ObservedObject ay isang Property Wrapper na nag-subscribe ng view sa mga pagbabago ng ObservableObject. Ang ObservableObject ay isang protocol mula sa Combine framework na nangangailangan ng implementasyon ng objectWillChange publisher. Kapag ang anumang property na may markang @Published ay nagbago sa loob ng ObservableObject, ang publisher ay nagpapadala ng signal, at ang SwiftUI ay nagre-redraw ng lahat ng view na naka-subscribe sa pamamagitan ng @ObservedObject.
Ang pangunahing katangian ng @ObservedObject ay kawalan ng pagmamay-ari. Ang view ay hindi responsable sa paggawa o pagsira ng bagay. Ang bagay ay ginawa sa parent view (sa pamamagitan ng @StateObject) o ini-inject sa pamamagitan ng @EnvironmentObject. Ang child view ay nagmamasid lamang ng mga pagbabago at tumatanggap ng mga update. Kung ang bagay ay pinalitan sa parent, ang @ObservedObject ay lumilipat sa bagong instance.
Ang @ObservedObject ay angkop para sa mga senaryo ng pagbabahagi ng data: modelo ng gumagamit, mga shared setting, status ng koneksyon sa server. Kapag maraming view sa iba't ibang antas ng hierarchy ang kailangang magpakita ng parehong data, ang @ObservedObject sa bawat view ay gumagawa ng independyente ngunit koordinadong mga subscription sa isang source.
Ang pagkakaiba sa pagitan ng @ObservedObject at @StateObject ay isa sa mga pinakakaraniwang paksa ng tanong sa mga panayam sa SwiftUI. Ang pangunahing tuntunin: ang @StateObject ay gumagawa at nagmamay-ari ng bagay, ang @ObservedObject ay nagmamasid ng umiiral na. Ang paglabag sa tuntuning ito ay humahantong sa hindi inaasahang pagkawala ng data o dobleng inisyalisasyon.
| Katangian | @StateObject | @ObservedObject |
|---|---|---|
| Paggawa ng bagay | Oo, sa inisyalisasyon ng view | Hindi, tumatanggap ng handa na |
| Pagmamay-ari | Kasalukuyang view | Parent component |
| Nag-iisang instance | Oo, sa buong lifecycle | Hindi, maaaring palitan |
| Pag-gawang muli sa render | Hindi, nananatili | Depende sa parent |
| Saan gagamitin | Root view na may-ari | Mga child view |
@StateObject ay ginagarantiyahan na ang bagay ay ginawa nang isang beses at nakaligtas sa paulit-ulit na inisyalisasyon ng istraktura ng view. Ang @ObservedObject ay tumatanggap ng bagay mula sa labas at muling ginagawa sa bawat inisyalisasyon ng istraktura ng parent. Kung ang parent ay gumagamit ng @StateObject para sa bagay, ang mga child view ay maaaring ligtas na mag-apply ng @ObservedObject — ang bagay ay magiging nag-iisa sa buong hierarchy.
Ang mekanismo ng pagsubaybay ng @ObservedObject ay nakabatay sa Combine at sa ObservableObject protocol. Sa inisyalisasyon, tinatawag ng SwiftUI ang objectWillChange publisher — ang bagay ay dapat maglabas ng signal bago baguhin ang @Published property. Ang Combine ay nagpapadala ng signal sa dependency graph ng SwiftUI, na nagmamarka ng lahat ng umaasang view bilang nangangailangan ng update. Ito ay nangyayari nang sabay-sabay bago ang pagbabago ng halaga.
class WeatherService: ObservableObject {
@Published var temperature: Double = 22.0
@Published var city: String = "Moscow"
}
struct WeatherView: View {
@ObservedObject var weather: WeatherService
var body: some View {
VStack {
Text("\\(weather.city)")
Text("\\(weather.temperature)°C")
}
}
}
Sa listing, ang WeatherService ay isang ObservableObject na may dalawang @Published property. Ang WeatherView ay nagdedeklara ng @ObservedObject var weather: WeatherService, na tumatanggap ng instance mula sa parent. Kapag nagbago ang temperature, ang objectWillChange ay nag-trigger bago itakda ang bagong halaga, nire-redraw ng SwiftUI ang WeatherView, at ang kasalukuyang temperatura ay ipinapakita. Ang subscription ay awtomatikong pinangangasiwaan ng SwiftUI — ang developer ay hindi kailangang tumawag ng sink o dispose.
Unang pattern — pagpasa ng modelo sa pamamagitan ng inisyalisador. Ang parent ay gumagawa ng ObservableObject sa pamamagitan ng @StateObject at ipinapasa ito sa mga child view bilang @ObservedObject. Ito ay isang karaniwang hierarchical na paghahatid ng data kung saan ang root view ay namamahala sa lifecycle ng modelo, at lahat ng nested na component ay nag-subscribe sa mga pagbabago.
Ikalawang pattern — EnvironmentObject, ang global na bersyon ng @ObservedObject sa pamamagitan ng SwiftUI Environment. Ang bagay ay ini-inject sa antas ng scene o root view at awtomatikong magagamit sa lahat ng child component nang walang tahasang pagpasa sa pamamagitan ng mga inisyalisador. Sa loob ng child view, ang @EnvironmentObject ay gumagana katulad ng @ObservedObject, ngunit kinukuha ang bagay mula sa kapaligiran.
Ikatlong pattern — komposisyon ng maraming ObservableObject. Sa mga kumplikadong application, ang view ay maaaring magmasid ng maraming bagay: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. Ito ay naghihiwalay ng responsibilidad sa pagitan ng mga serbisyo at nagpapanatili ng testability ng bawat component.
struct DashboardView: View {
@ObservedObject var user: UserViewModel
@ObservedObject var network: NetworkMonitor
var body: some View {
VStack {
Text("Maligayang pagdating, \\(user.name)")
HStack {
Circle()
.fill(network.isConnected ? Color.green : Color.red)
.frame(width: 10, height: 10)
}
}
}
}
DashboardView ay nagmamasid ng UserViewModel at NetworkMonitor. Bawat bagay ay responsable para sa sarili nitong domain ng data at independyenteng nag-aabiso sa view tungkol sa mga pagbabago. Kung ang network ay madiskonekta, binabago ng NetworkMonitor ang isConnected, at nire-redraw ng SwiftUI ang DashboardView, ina-update ang kulay ng indicator. Ang komposisyon ng ObservableObject ay ang mas pinipiling paraan ng pag-oorganisa ng data sa mga SwiftUI application.
@Published ay isang Property Wrapper mula sa Combine na awtomatikong nagdaragdag ng publisher sa isang property sa loob ng ObservableObject. Kapag nagbago ang @Published property, ang Combine ay bumubuo ng event sa pamamagitan ng objectWillChange publisher. Ang SwiftUI ay nag-subscribe sa publisher na ito kapag gumagamit ng @ObservedObject o @StateObject at nagre-redraw ng view sa bawat bagong halaga.
Ang @Published ay sumusuporta sa lahat ng uri, kabilang ang mga opsiyonal, koleksyon, at custom na istraktura. Gayunpaman, para sa mga koleksyon (array, diksyunaryo) ang SwiftUI ay sinusubaybayan lamang ang pagpapalit ng reference, hindi ang pagbabago ng nilalaman. Upang matukoy ang pagdaragdag o pag-alis ng elemento, kailangan mong muling italaga ang buong koleksyon o gumamit ng ObservableObject na may manual na objectWillChange.send().
Mahalagang detalye: @Published ay dapat na nasa loob lamang ng isang klase na nagpapatupad ng ObservableObject. Ang paggamit ng @Published sa labas ng ObservableObject ay magdudulot ng error sa compilation. Gayundin, ang @Published ay hindi maaaring ilapat sa mga property na may lazy initialization (lazy var) o computed property.
Ang pinakamahalagang pagkakamali — ang paggamit ng @ObservedObject upang gumawa ng bagay. Kung isusulat mo ang @ObservedObject var model = UserViewModel() sa parent view, sa bawat render ay gagawa ng bagong instance ng UserViewModel. Mawawala ang data, at ang mga @Published subscription ay muling gagawin. Palaging gamitin ang @StateObject para sa paggawa at @ObservedObject lamang para sa pagtanggap ng handa na bagay.
Ikalawang pagkakamali — pagbabago ng @Published property sa labas ng pangunahing thread. Ang ObservableObject ay gumagamit ng Combine, na nangangailangan ng pagpapadala ng mga pagbabago sa pangunahing thread (main actor). Kung babaguhin mo ang @Published sa background queue, maaaring i-redraw ng SwiftUI ang view sa hindi angkop na oras, na magdudulot ng race conditions. Gamitin ang DispatchQueue.main.async o @MainActor para sa pag-update.
Ikatlong problema — mga paikot na update. Kung ang pagbabago ng @Published ay may kasamang side effect na muling nagbabago ng @Published, magkakaroon ng walang katapusang loop ng pag-redraw. Solusyon: gumamit ng mga flag na pananggalang (isUpdating) o paghiwalayin ang lohika sa iba't ibang ObservableObject na may malinaw na hangganan ng responsibilidad.
Mga Madalas Itanong
Oo, sinusuportahan ng SwiftUI ang @ObservedObject var model: UserViewModel?. Gayunpaman, ang view ay hindi mag-subscribe sa mga pagbabago habang ang bagay ay nil. Kapag nagtalaga ng halaga, ang subscription ay awtomatikong nag-a-activate.
@ObservedObject ay tumatanggap ng bagay sa pamamagitan ng inisyalisador, @EnvironmentObject sa pamamagitan ng SwiftUI Environment. Ang @EnvironmentObject ay hindi nangangailangan ng tahasang pagpasa sa pamamagitan ng mga constructor, ngunit ang bagay ay dapat na ini-inject sa itaas na antas ng hierarchy.
Tawagan ang objectWillChange.send() bago baguhin ang property. Ito ay kapaki-pakinabang kung ang @Published ay hindi angkop (halimbawa, para sa mga computed property o operasyon sa koleksyon kung saan kailangan iulat ang pagbabago bago ang mutasyon).
@ObservedObject at @Published ay sinusubaybayan ang pagpapalit ng reference, hindi ang mutasyon ng nilalaman ng koleksyon. Para sa pag-redraw, kailangan mong muling italaga ang array: items.append(newItem) → items = items o gumamit ng objectWillChange.send() bago ang mutasyon.
Hindi, ang @ObservedObject ay isang SwiftUI Property Wrapper na magagamit lamang sa loob ng mga uri na nagpapatupad ng View protocol. Para sa mga ordinaryong istraktura, gamitin ang Combine nang direkta sa ObservableObjectPublisher.
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