I think the idea of withObservationTracking
is if you are supposed to read the property within it and if there is a change which you don't read again then you are no longer interested in changes thus there should be no more change tracking. The example in Apple's docs is not great because it doesn't demonstrate it is possible to return something from withObservationTracking
.
Below is an object that maintains a sorted order of the a parent model's objects. I used withObservationTracking
to update if either the sort order local to this object is changed or if the particular model object property I'm sorting by is changed or even the model itself. It doesn't matter that tracking only happens once, because if anything I'm tracking changes, the cached data will be invalidated and when it is read again the tracking will be re-configured.
@Observable
class Counter: Identifiable {
var count = 0
}
@Observable
class Model {
var counters: [Counter] = [.init(), .init(), .init()]
}
@Observable
class SortedModel {
var _model: Model!
var model: Model {
get {
_model
}
set {
_model = newValue
_counters = nil
}
}
var ascending = false
var _counters: [Counter]?
var counters: [Counter] {
if _counters == nil {
_counters = withObservationTracking {
// tracks self.ascending and the count of all model.counters.
let sort = SortDescriptor(\Counter.count, order: ascending ? .forward : .reverse)
return model.counters.sorted(using: sort)
} onChange: { [weak self] in
self?._counters = nil
}
}
return _counters!
}
}