Section 8/131 menit
8. Perbandingan: ObservableObject vs @Observable
8. Perbandingan: ObservableObject vs @Observable
| Aspek | ObservableObject + @Published |
@Observable |
|---|---|---|
| Framework | Combine (tidak tersedia di Linux) | Observation (Swift standard) |
| Granularitas | Per-object (all-or-nothing) | Per-property (fine-grained) |
| Boilerplate | @Published di setiap property |
Tidak ada anotasi per-property |
| Binding | @ObservedObject, @StateObject, @EnvironmentObject |
@State, @Bindable, @Environment |
| Thread safety | Tidak otomatis | Tidak otomatis |
| iOS/macOS minimum | iOS 13 / macOS 10.15 | iOS 17 / macOS 14 |
| Performa rendering | Sering over-render | Minimal re-render |
| Non-SwiftUI support | Via Combine publisher | Via withObservationTracking |
| Swift 6 compatibility | Perlu extra annotation | Lebih natural dengan @MainActor |
| Nested observable | Tidak otomatis | Otomatis (nested @Observable di-track) |
Contoh Nested Observable
swift
// ObservableObject — nested TIDAK otomatis di-observe
class AddressViewModel: ObservableObject {
@Published var city: String = ""
}
class UserViewModel: ObservableObject {
// Perubahan di nested.city TIDAK akan men-trigger UserViewModel.objectWillChange
// Harus subscribe manual ke nested.objectWillChange dan forward ke self.
var address = AddressViewModel()
private var cancellable: AnyCancellable?
init() {
// Boilerplate manual untuk propagate nested changes
cancellable = address.objectWillChange
.sink { [weak self] _ in self?.objectWillChange.send() }
}
}
// @Observable — nested OTOMATIS di-track
@Observable
final class Address {
var city: String = ""
}
@Observable
final class UserViewModel {
// Perubahan di address.city otomatis di-track oleh SwiftUI
// yang mengakses viewModel.address.city di body-nya.
var address = Address()
}