※これは iOS/Android モバイルデータベース Realm についての記事です。詳しくは以下をご参照ください。
Webサイト: realm.io、Facebookグループ: Realm Japan User Group、質問: Slack Channel
--
☆ 7/16(木)14:00~ に行われた Realm オフィスアワーの質問 & 回答一覧です。
この時点での Realm のバージョンは、それぞれ realm-cocoa 0.93.2 と realm-java 0.81.1 です。ご注意ください。
Realm で RealmDictionary のようなものはあるか?
RealmDictionary のようなデータ構造をサポートするのは、タスクにはあるがまだ存在していない。
似たようなことを Realm でやる場合は、下記のようなものを自作する必要がある。
class RealmDictionary: Object {
dynamic var key: String = ""
dynamic var value: String = ""
}
状況として、JSON をRealmに保存したい場合で、ただしキーと値の組み合わせが動的に変わるので、保存するときに Dictionary のような仕組みが欲しいというものだった。中身が可変のものをどうするかは難しいが、キーが可変でも構造が一定であれば上記のような辞書のようなものを作れば、なんとかなる。
TableView をスクロールするとアプリが落ちる
'RLMException', reason: 'Index is out of bounds.'
という例外が出ている。
結果の更新と表示しているところの整合性が取れなくなっている可能性がある。つまり、Realm に保存されているモデルの件数と表示されているテーブルビューの件数が合わなくなっている。
おそらく、別のスレッドで更新を行っているところに問題があると思われる。
基本的に、Realm のインスタンスをそれぞれのスレッドで作っていれば、同じファイルにアクセスするのは問題はないが、更新は即座に Realm インスタンスおよび Result にも反映されるため、あるスレッドで更新処理が行われたが、TableView が認識している件数が以前のままである可能性が考えられる。
Realm は、MVCC(MultiVersion Concurrency Control) という方法で更新を管理しており、書き込み処理が行われてるときでも読み込み処理が行えるという大きな特徴がある。
よって、トランザクションの最中は古いデータが返り、書き込みが終了したあとに読み込むと新しいデータが読み込まれるがそこで、不整合が生じているかもしれない。
暗号化された Realm を Realm Browser で開くことはできるか?
Realm Browser は暗号化された Realm ファイルを開くことはできない。
開発中であれば、リリースビルドだけ暗号化して、デバッグビルドは暗号化しないというのが簡単な解決方法である。暗号化のユースケースとして、実際に暗号化されたユーザーデータは開発元でも見れないのが普通なので、トラブルシューティングが必要になる場合は、そもそも暗号化する範囲を分けるなど、工夫するのがオススメ。
暗号化された Realm を Realm Browser で見るのはサポート予定である。
一つの iOS アプリに割り当てられるメモリサイズはどれくらい?
ここのドキュメントにある「一つの iOS アプリに割り当てられるメモリサイズ」についてもう少し詳しく教えてほしい。
Realm ファイルのサイズは、一つの iOS アプリに割り当てられるメモリサイズを超えてはいけません。割り当てられるメモリサイズは、デバイス毎に違い、また、どのくらいメモリのフラグメンテーションが進んでるかにも依存します。(ここについては、Open Radar の rdar://17119975 をご覧ください) これ以上のデータを保存される場合は、Realm ファイルを複数に分けご使用ください。
デバイスや、他のプロセスがどれくらい使ってるのかにもよりますが、Realm ファイルサイズが500〜700MB あたりを超えると、メモリ不足によりファイルのオープンに失敗する可能性が高い。メモリ不足の状態だとファイルのオープンに失敗する。
Realm のファイル読み書きには Memory mapped file を使ってるので、mmap
に失敗すると使うことができない。OSX だと数GBの Realm ファイルでも難なく扱える。
モデル1つのデータが多い場合は注意で、たとえば、青空文庫のテキストや辞書のテキストを全部扱いたい場合などは、目次と本文を別のファイルに分けるなど工夫が必要である。
ファイルオープンに失敗したとき、どのようにしてそれを取得できるのか?
メモリ不足により mmap()
に失敗するとコアのレイヤーから例外が発生する。ただ、キャッシュのデータなどで Realm 使っている場合、それを消してリカバリ可能にできる方法が提供できないか realm-cocoa チームと相談してみる。
iOS7 + Swift で RealmSwift が使えるか?
RealmSwift のコードには Framework 内で使うことを前提にしたコードがあるので、iOS8以上でしか使えない。具体的にはこのあたり。
iOS7 の Swift コードからRealm を使いたい場合は、Objective-C 版の Realm と SwiftSupport.swift を使うようにしてください。Objective-C 版の方にも Generics のサポートや Nullable annotation を付いたり改善はされていので、以前よりも Swift から扱いやすくはなっている。Generics のコードはまだマージされていないが、すぐにマージされる予定。(7/16現在)
Nullablity のコードはマージされているので、次のリリースで入る。
--
デベロッパーの Realm オフィスアワーは月に一度、Slack で開催していますが、オフィスアワー関係なくいつでもご質問ください。
Realm Slack Channel → http://slack.realm.io/