💨
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