Swift の willSet や didSet に想いを馳せる

そういえば Swift の willSet や didSet って使ってて不思議な感じがするなと思ったりして、そんなあたりに想いを馳せてみたときのツイートをまとめておきます。
0
ezura @eduraaa

.@es_kumagai さんに教えて貰った「IBOutlet に didSet 使う」のすごい使える。これは素晴らしい(’ω’) gist.github.com/6bd3d35fe15b71… #swift pic.twitter.com/56oHUBzoG9

2016-05-15 16:45:13
拡大
ezura @eduraaa

実は didSet 大好き。状態によって View の見た目変わるの実装したいときとか、綺麗にかけて好き。

2016-05-15 18:15:50
ezura @eduraaa

このとき、これをあんまり「state の変化をフックして何か処理する」って意識で考えてなくて、「状態 = 見た目」を定義してる感じ。 実質、フックなんだけど。。

2016-05-15 18:16:37
熊谷 友宏 @es_kumagai

ん…!もしかして今、この上なく脈絡ないですけれど didSet な変数の美しい使い道を閃いた気がする!

2016-05-18 11:12:27
熊谷 友宏 @es_kumagai

さて、話が落ち着いたところで途中突如閃いた話に戻るんですけど…ああ、プロパティの発想と同様に紐づけられそうかもと思ったんですけど、期待は花と散りました。 gist.github.com/56ac1630f7da4a… #swift pic.twitter.com/GNEPciIPKu

2016-05-18 12:23:17
拡大
熊谷 友宏 @es_kumagai

なるほど。それだと実行されなくない?っていうのはきっとこれのことね。

2016-05-18 12:25:57
熊谷 友宏 @es_kumagai

他にも、もしこれがプロパティだったら init 内で初期化するときにも didSet が呼ばれないというのがあります。よくよく見れば、今の自分のコードがまさにそれでしたね。

2016-05-18 12:27:06
熊谷 友宏 @es_kumagai

先ほどのコードもこんな感じで書けば didSet は発動するけれど、これなら @akio0911 さんに教えて貰ったプロパティ的なゲッター記述の変数の方がだんぜん優位ね。 gist.github.com/15d701890137a0… #swift pic.twitter.com/0xrVQEuPA1

2016-05-18 12:29:47
拡大
熊谷 友宏 @es_kumagai

自分はこれまでこういう処理をしたい時に、オレオレフレームワークを使ってこんな風に表現してたので、もしかしてこれを標準機能で描き直せるかもと思ったけれど、オシイ。 gist.github.com/a24340d521e900… #swift pic.twitter.com/3ebGXYdzZf

2016-05-18 12:33:13
拡大
熊谷 友宏 @es_kumagai

didSet は初期化の時だけそれが切り離されてしまうのが悩ましいところですね。それには明確な意志があるのかなって思いを巡らせてみたときに、もしかして初期化のときは自分自身の他の機能を使うことを約束できないからというのもあるのかもしれない。awakeFromNib と同じ調子で。

2016-05-18 13:31:41
熊谷 友宏 @es_kumagai

そう考えれば、もしかするととても自然なことで、最初の初期化はきっちり初期値で意図的に合わせて、その後に自身の中での状態の相互矛盾を生まないために didSet が生きてくると捉えて良さそう。

2016-05-18 13:33:36
熊谷 友宏 @es_kumagai

なるほど、たしかに IBOutlet もその一環にたぶんぴったり収まりますね。

2016-05-18 13:34:52
熊谷 友宏 @es_kumagai

あともうひとつ didSet の面白い挙動をいくらか前に見せてもらったけれど、再現方法を忘れてしまった。それを踏まえるとまた面白い世界観が見えたりしそうね。

2016-05-18 13:59:25
熊谷 友宏 @es_kumagai

ちなみに初期化と didSet の分離の話。分離したくなければそもそもの入れ物と計算を分離する、要は別にストレージとしての保存型プロパティを用意してそれを計算型プロパティでラップする方法もある…と思いましたけど、これも結局、挙動的に一緒になるのね。面白い。

2016-05-18 14:08:15
熊谷 友宏 @es_kumagai

分けたところで、結局はストレージ側を初期化しないといけないし、初期化したところで別に関連付けた didSet … ここでは set が発動されるわけでもなくて。一緒だ。 gist.github.com/8f8adcf6c12a39… #swift pic.twitter.com/17Vy6o6VAL

2016-05-18 14:12:28
拡大
熊谷 友宏 @es_kumagai

保存型プロパティを計算型プロパティで表現するとしたら、気持ち的というか手続き的には、たぶんこんな印象かな? gist.github.com/fb1a50a5956622… #swift pic.twitter.com/ypxKbPHGGs

2016-05-18 14:19:00
拡大
熊谷 友宏 @es_kumagai

あ!たぶんきっと思い出せた! そうそう、この前 @eduraaa さんに見せてもらった世界はこれで近かったはず…! gist.github.com/5500a043489ff8… #swift pic.twitter.com/8Si4RCr1ct

2016-05-18 15:17:01
拡大
熊谷 友宏 @es_kumagai

あの日、対して自分は inout の観点で話を返した記憶がありますけれど、そこからちょっと頭を離して。きっとこんなあたりも踏まえて想像を膨らませると、そもそもの willSet や didSet の存在意義みたいな根本的なところから違う世界が窺えてきそうな、そんな予感で溢れてる。

2016-05-18 15:17:52
熊谷 友宏 @es_kumagai

なんか、まだ不完全なひらめきを言葉に乗せるだけですけれど、どことなく didSet とかって出力というよりむしろ入力?っぽいようにも感じるような気もするような。

2016-05-18 15:20:02
熊谷 友宏 @es_kumagai

そんなことを言ってる自分自身がぜんぜんわかってないんですけど、なんか didSet の存在にときどき、かつて子どもの頃に「メモリマップド I/O』の存在を知ったときの記憶がなんか、重なるような気がするんですよね。QT: goo.gl/kNSdaP

2016-05-18 15:24:30
熊谷 友宏 @es_kumagai

I/O だから、入力だけでなく出力も伴うわけですけれど、プロトコルの世界観も踏まえた時には、プロトコルで規定された get set プロパティというのは、ちょうどそんな性質を持ってくれるような気がしてみたり。set については型側に依存するわけですけど。だから、入力と感じる?

2016-05-18 15:29:35
熊谷 友宏 @es_kumagai

なんか、感覚が不思議になってきた。プロトコル側から眺めていた時に set も get も入力なようにも思えてきた。なんか頭がどこかで崩壊してそう。

2016-05-18 15:31:00
熊谷 友宏 @es_kumagai

もしかして『単方向』『相方向』とかいう意味合いかしら。完全にこれもひらめきですけど。

2016-05-18 15:32:48
熊谷 友宏 @es_kumagai

自分の価値観的に『単方向』が 型 → プロトコル というのはあまり考えにくそうだから、そうすると set は必ず get を伴うことについてもこれらの言葉で説明が付きそうな気もするけれど、とりあえずそれは現段階では辻褄合わせ。いわゆる仮説ね。

2016-05-18 15:36:19