😎

ObservableObjectはもう古い?iOS 17の`@Observable`マクロがもたらすモダンな状態管理

に公開

はじめに

SwiftUIで真っ先に学ぶ状態管理と言えば ObservableObject@Published。しかし iOS 17 から登場した @Observable マクロは、その常識を静かに更新しつつあります。本記事では両者の違いと選択基準をまとめます。


ObservableObject × @Published の基本と課題

  • 通知はクラス単位 ― プロパティ単体の変更検知は出来ず、無駄な再描画が起きやすい。
  • ボイラープレートObservableObject 準拠と各プロパティへの @Published が必須で冗長。
  • 入れ子の観測が手間 ― 子オブジェクトの変更を伝播させるには工夫が必要。
class CounterModel: ObservableObject {
    @Published var count = 0
}

@Observable マクロとは

何が変わる?

  • プロパティごとに差分検知: 使われていない値の更新ではビューを再描画しない。
  • シンプルな宣言: ObservableObject@Published を書く必要がない。
  • 入れ子の監視が自然: ネストしたクラスも自動的に観測対象に。
import Observation

@Observable
class CounterModel {
    var count = 0
}

性能面

Apple の WWDC セッションでも触れられたとおり、レンダリング効率が大幅向上。実測でも再描画数が減りやすい。


注意点と制約

項目 @Observable
対応OS iOS 17+ / macOS 14+
対象 クラスのみ (構造体は未対応)
保持方法 ビュー内で @State@StateObject で保持すると安全

Tip: iOS 16以前をサポートする場合は依然として ObservableObject を併用する必要があります。


もう一歩先へ——Composable Architecture (TCA)

アプリ規模が大きくなるとPoint‐FreeThe Composable Architecture が選択肢に。状態、アクション、リデューサを明確に分離し、テスト容易性と拡張性を確保できます。


まとめ:どれを選ぶ?

規模/要件 推奨アプローチ
小〜中規模 / iOS 17+ @Observable 一択。シンプル、高効率。
マルチOS対応 (iOS 16以下含む) ObservableObject + @Published を継続使用。
大規模 / 高テスト性 @Observable + TCA でスケールさせる。

@Observable は「常に最新が正義」ではありません。ターゲットOSとプロジェクト規模を踏まえ、最適な手段を選びましょう。

Discussion