T2ListとT2ListFaceについて覚え書き

 そもそもThousandのスレッドリスト掲示板はT2ListHolderというので管理してたんだけれど、それをT2ListとT2ListFaceにすることについて覚え書き。

T2ListHolderは実に単純な構造をしていて、インスタンス変数にあるのは基本的に

  • 内部パス
  • タイトル
  • 中身のNSArray

くらい*1
 中身のNSArrayには他のT2ListHolderや、T2ThreadListItemを入れていた。もちろん、現在表示されているT2ListHolderしか中身のデータというのは必要がないので、適宜ロードと解放をしていた。loadとunloadというメソッドがそれだった。コントローラはあるT2ListHolderが選択されたらそれをloadし、今まで選択されていたものをunloadしていた。ファイルからの読み込み/保存もこのタイミングだった。
 けれどこれじゃうまくいかないってのは分かると思う。例えば、2つブラウザウィンドウを開いて同じ板を表示させたとして、片方の板の選択を外す。板にあたるT2ListHolderオブジェクトは共有されているから、二つのブラウザは同じものを表示している。そこにunloadが送られると中身は空になってしまうわけだ。
 これを防ごうとすると例えば、loadで+1し、unloadで-1するloadCountなんてものを導入したりする羽目になる。なんでretainCountと同じようなことを自前でやらにゃならんのだ。
 じゃあ中身のデータを解放しない、って手もある。ただそうすると、2chの全板について一回読み込んだ後はデータがメモリに残ることになる。というのも、T2ListHolderは上位のT2ListHolderの「項目」でもあるからである。
 オブジェクトを共有しない、って手もあるかもしれない。けどこれは、一つのブラウザでリロードした結果がもう一つの方で反映されない、って結果を招く。おまけに、ファイルへの保存を別々のタイミングでやるだろうから、滅茶苦茶になる。

 そこで2つのクラスに分けることにした。T2ListはT2ListHolderと同じ役割を持つけど、T2ListFaceはT2Listの内部パスやタイトル、アイコンだけを保持する。今まで、T2List→T2List→T2ThreadListみたいに(参照の)階層構造があったものは、T2List→T2ListFaceだけになる。そこからさらに辿る際にはT2ListFaceに、お前の表してるT2Listをおくれ、って頼むことになる。
 さらにT2ListFaceは、それ自身が表すT2Listのインスタンス変数でもある。何せタイトルやアイコンはこいつが持ってるわけだから。そして、あるT2Listが自身のタイトルやアイコンを変える時には自身を表すT2ListFaceのタイトルやアイコンを変えることになる。すると、そのT2ListFaceの上位の階層のT2Listが、自身の内容のNSArrayをNSTableViewなんかにBindしていれば勝手に表示は切り替わるわけである。

Core Dataなり、データベースなフレームワークを使ったりすればまた違うのだろうけど。素人がハンドメイドでやるとこんな設計になるってわけです。

*1:アイコンとか他色々あるけど