withObservationTracking срабатывает ровно один раз ⚠️
🔍 withObservationTracking(_:onChange:) даёт реагировать на изменения @Observable-модели откуда угодно — из сервиса, менеджера, актора, а не только из SwiftUI-вьюхи. Одно чтение блока apply регистрирует все прочитанные свойства сразу. Дальше onChange срабатывает один раз и снимает регистрацию — в реализации там буквально onChange(); tracking.cancel(). Хотите наблюдать дальше — перерегистрируйтесь внутри onChange.
⚠️ Про тайминг: onChange — это willSet-обработчик. Он вызывается синхронно внутри сеттера до того, как новое значение записано. Читать актуальное значение прямо в onChange нельзя. А вот совет «отправьте в следующий runloop» — это фольклор. Требование ровно одно: прочитать после записи. Task { @MainActor in … } это обеспечивает, но никакого порядка относительно других мутаций не гарантирует.
💡 Что дальше: SE-0506 «Advanced Observation Tracking» уже принят (Swift 6.4) и наконец добавляет явные опции .willSet / .didSet / .deinit и withContinuousObservationTracking, чтобы не перерегистрироваться руками.
· 05.08
пока se-0506 не в проде, перерегистрацию лучше сразу зашить в один рекурсивный хелпер на ~10 строк, а не размазывать по каждому сервису. у нас на проекте именно ручная перерегистрация в onChange была источником тихих багов — кто-то забывал, подписка молча умирала, и дебажить это без крэша та ещё радость
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён