💨
AppStorageにCodableを保存する時に気を付けたいパフォーマンスの話
AppStorageにオブジェクトを保存する場合、CodableとRawRepresentableの組み合わせを使ってJSONのStringとして保存するテクニックがあります。
非常に強力なのですが、この実装部分でUIスレッドがハングする問題に当たったので原因と解決策を紹介します。
原因と解決策
SwiftUIでは、差分検知のためにEquatableが使われます。
Equatableは、その構造体が持つすべてのプロパティがEquatableであればそれらを連結した結果を自身の等価判定に利用します。
しかし、RawRepresentable, Equatableの場合、Equatableの実装はrawValueを比較するように実装されています。
これによって、値の比較が行われるたびにCodableの重いデコード・エンコード処理が行われUIスレッドをハングさせていたというわけです。
この問題はEquatableを自前で実装することで回避することができます。
struct Session: RawRepresentable, Equatable {
...
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.id == rhs.id
}
}
Discussion