Realm + 高さが可変するTableViewの考察

f:id:yoneapp:20160229102101p:plain

何度か、Realm + 高さが可変するTableViewにチャレンジしてみて、自分の中で最終的にこんな感じかなと思ったのでサンプルを作成してみました。アドバイス頂けると嬉しいです。

GitHub - yoneapp/RealmTableViewSample

高さを計算する処理が重く、バックグラウンドに逃したいがRealmはスレッドをまたげないのでバックグラウンド処理において、どう書けばいいのかについて悩み続けています。

ここに至った経緯を記します。現在、四個目です。

一個目

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat にて text.boundingRectWithSize を使用して高さを計算する。もちろん text.boundingRectWithSize をMainThreadで実行すると重い。

二個目

バックグラウンドで text.boundingRectWithSize を実行する。もちろん、Realmを使っているので落ちる。また、上手くごまかせたとしてもデータが書き換わった時に対処しにくい。

三個目

全てのデータをRealmから取り出し、普通のオブジェクトにしてしまう。この場合、Realmの遅延評価による高速性を犠牲にする。また、データが何千件もある場合に処理に時間が掛かる。更新にも時間がかかる。

四個目

仮想のCellを作成して、そこで高さ計算を行う。Realmオブジェクトに識別子を付け、仮想のCellと結びつける。仮想のCellの計算が終わってない場合は、仮のセルを表示しておく。

仮想のCellは、現在表示されてるCellのプラスマイナス5個ぐらいを常にバックグラウンドで計算するようにする。

実際にRealmのデータが削除された場合でも、データがない場合は仮のセルが表示されるのでクラッシュせずに動作します。

五個目

RealmのSlackで質問させて頂いた所、複雑なことをしなくても UITableViewAutomaticDimension で解決できるとアドバイス頂きました。実際の所、高さ計算はそんなに重くないようでした。estimateHightを合わせて使えば、計算されるセルの数も限定できるので簡単に実装することができそうです。