I thought I'd share an example of how I am currently using it. I wanted to make an object that maintains a sorted order of the main 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. 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 requested 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 {
@ObservationIgnored
var model: Model! {
didSet {
if oldValue !== model {
_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!
}
}