5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

@StateでdidSetは使うな。 (SwiftUI)

Posted at

内容

@Stateのpropertyの変更を検知するときは、didSetを使ってはいけない。onChange(of:perform:)を使え。という話です。

きっかけ

swift-developers-japan
@StateにdidSetを書いちゃダメという記事を見たが自分で実際に書いたらdidSetが呼ばれた。本当にダメなのか?
という趣旨の質問があり、あまり理解できていなかったので調べた。

なぜ@StateでdidSetを使ってはいけないか

@StateのdidSetは呼ばれないことがある。
いつ呼ばれていつ呼ばれないかというと、

@State var num: Int
@Binding var binding: Int
_binding = $num

で定義されているとして

num = 10 // didSet呼ばれる
_num.wrappedValue = 15 // 呼ばれない
binding = 2 // 呼ばれない

という感じになります。

これは@StateのwrapperValueがnonmutatingでwrappedValueを更新しても@Stateの値自体は変更されないためのようです。
mutaitngのsetterを持つproperty wrapperを自作してwrappedValueの値を直接更新したら、同様にdidSetは呼ばれませんでした。

これは、property wrapperを使っているからで、wrappedValueの値を変更してもそのproperty wrapperを適用しているproperty自体は変更されないためのようです。

ではどうする?

onChange(of:perform:)を使う。
試してないですが、iOS13では.onReceive(Just(selection))で同様のことができるみたいですlink

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?