2017/06/16追記
いつの間にかこのような場合の正しい方法が公式docに記載されてました。
今後はこっちを参照してもらうほうが良いです。
https://realm.io/docs/java/latest/#iterations--snapshots
ただし、何らかの理由で、新しいバージョンが使えない人たち向けにこの情報は残しておきます。
古い情報だよ!
Realmを使っていて、ある条件にヒットするデータを探して、検索に使用した値をアップデートしたいことってよくあると思います。
具体的に言うとこういうコードの場合
mRealm.beginTransaction();
RealmResults<Obj> results = mRealm.where(Obj.class).equalTo("status", 0).findAll();
int resultCount = results.size();
for (int count = 0; count < resultCount; ++count) {
Obj obj = results.get(count);
obj.setStatus(1);
}
mRealm.commitTransaction();
これ、行けそうに見えて、実際に実行すると、java.lang.ArrayIndexOutOfBoundsExceptionが発生してひどく悲しい気分になれます。
某所で質問したところ、最初の検索条件に使用しているパラメーターを途中で書き換えているためにRealmResults<Obj>
自体が更新され配列が減っているために起こっているとのこと。
なので正解のコードはこんな感じになるらしい。
mRealm.beginTransaction();
RealmResults<Obj> results = mRealm.where(Obj.class).equalTo("status", 0).findAll();
while(results.size() > 0){
Obj obj = results.get(0);
obj.setStatus(1);
}
mRealm.commitTransaction();
iteratorを使えという話はこんなことになっているので無理ということで。
ConcurrentModificationException when using iterators methods #640
https://github.com/realm/realm-java/issues/640
自動更新を止めるAPI追加の方向で動いているらしい
https://github.com/realm/realm-java/commits/stk/waitforchange