NSArrayControllerのNSPredicateの使い方

改良のつもりが、大改造になってしまい、リリースできる状況に無くなってしまって、遊びか勉強か分からなくなってしまったKIMwitterの開発、細々とやっております。

大したことではないけれど、グーグル先生が教えてくれなかったことなのでメモしておこうと思う。

KIMwitterでは、データをCore Dataを使って保存・管理している(SQLite3形式)。で、ビューは元々Cocoaバインディングで自動生成したNSCollectionViewを使っていたので、NSArrayControllerを介して接続されている。

今は、描画が遅いのと、速度面の改善を狙って、NSTableView+カスタムセルへの改造中なのだ。

で、現状のKIMwitterには「My」タブという表示形式がある。

自分のツイートだけを表示するページで、一種の逃げの実装でもあるのだが、削除をするページという役割を負わせてもいる。当然、データの実体は、タイムラインと同じ、NSManagedObjectContextを使い回している。で、NSPredicateでTwitterのスクリーンネーム(ユーザ名)でフィルタを掛けて自分のツイートだけを表示していた。

今まで、NSArrayControllerクラスのインスタンスメソッド、setFilterPredicate:を使ってきた。しかし、これをデバッガコンソールで見ると、SQL発行の時点では全件取得してきており、ビューに出す時点で絞り込んでいる。これではメモリにやさしくない。どうやって、SQLの「WHERE句」を設定したらいいのか?

グーグル先生を使っても、NSFetchRequestを使う答えばかり。大半がiPhoneSDKのものばかりで、役立たず。ビューが絡むとMac OSとiPhone SDKで全く違うから情報として早く立たない。NSArrayControllerは目には見えないけど、InterfaceBuilderで使うクラスなので私の中では「ビュー」側に属するクラスになります。

で、何気にクラスリファレンスで、NSArrayControllerの親クラス、NSObjectControllerという今まで見たこともないクラスのリファレンスを見ると、「setFetchPredicate:」というインスタンスメソッドがある。名前がいい感じだ。ということで、このメソッドに置換すると、SQLのWHERE句に条件が追加され、Fetch速度が上がった。一つ解決。

InterfaceBuilderのNSArrayControllerのプロパティには「Fetch Predicate」という、条件式を生で書く欄があるので、それを動的に設定することに相当するメソッドと見た。使える。

さて、ビューにこだわるか、ビューを元に戻して、他の部分の改良で一旦リリースしておくか、バグが溜まっているので考えどころ。

コメント