Realm提供 MutableRealmInteger (数值包装器),以帮助更好地同步多个客户端之间的数值更改。
通常,递增或递减 Realm 对象的 byte 、 short 、 int或long字段如下所示:
读取字段的当前值。
根据递增或递减,将内存中的该值更新为新值。
将新值写回该字段。
当多个分布式客户端同时尝试此操作时,以不同顺序到达客户端的更新可能会导致不同客户端上的值不同。 MutableRealmInteger对此进行了改进,将数值更新转换为可以按任何顺序执行以收敛到相同值的同步操作。
MutableRealmInteger 字段由传统数字类型支持,因此将字段从byte 、 short 、 int或long更改为MutableRealmInteger时无需迁移。
以下示例演示了一个MutableRealmInteger字段,该字段计算在鬼屋中发现的鬼魂数量:
import io.realm.MutableRealmInteger; import io.realm.RealmObject; import io.realm.annotations.Required; public class HauntedHouse extends RealmObject { private final MutableRealmInteger ghosts = MutableRealmInteger.valueOf(0); public HauntedHouse() {} public MutableRealmInteger getGhosts() { return ghosts; } }
import io.realm.MutableRealmInteger import io.realm.RealmObject import io.realm.annotations.Required open class HauntedHouse: RealmObject() { val ghosts: MutableRealmInteger = MutableRealmInteger.valueOf(0) }
重要
计数器字段必须为最终字段
MutableRealmInteger 是一个活动对象,如RealmObject 、 RealmResults和RealmList 。 这意味着写入 Realm 时, MutableRealmInteger中包含的值可能会发生变化。 MutableRealmInteger因此,Java 中的 字段必须标记为val final,Kotlin 中的 字段必须标记为 final。
使用
counter.increment()和counter.decrement() 操作符确保来自多个分布式客户端的递增和递减正确聚合。
要更改MutableRealmInteger值,请在写事务中调用increment()或decrement() :
HauntedHouse house = realm.where(HauntedHouse.class) .findFirst(); realm.executeTransaction(r -> { Log.v("EXAMPLE", "Number of ghosts: " + house.getGhosts().get()); // 0 house.getGhosts().increment(1); Log.v("EXAMPLE", "Number of ghosts: " + house.getGhosts().get()); // 1 house.getGhosts().increment(5); Log.v("EXAMPLE", "Number of ghosts: " + house.getGhosts().get()); // 6 house.getGhosts().decrement(2); Log.v("EXAMPLE", "Number of ghosts: " + house.getGhosts().get()); // 4 });
val house = realm.where(HauntedHouse::class.java) .findFirst()!! realm.executeTransaction { Log.v("EXAMPLE", "Number of ghosts: ${house.ghosts.get()}") // 0 house.ghosts.increment(1) Log.v("EXAMPLE", "Number of ghosts: ${house.ghosts.get()}") // 1 house.ghosts.increment(5) Log.v("EXAMPLE", "Number of ghosts: ${house.ghosts.get()}") // 6 house.ghosts.decrement(2) Log.v("EXAMPLE", "Number of ghosts: ${house.ghosts.get()}") // 4 }
您可以通过调用counter.set()为MutableRealmInteger分配新值 在写事务中。
警告
计数器重置
使用set()操作符时要格外小心。 set()忽略之前调用increment()或decrement()的影响。 尽管MutableRealmInteger的值在跨设备时始终收敛,但其收敛的具体值取决于操作发生的实际顺序。 除非可以接受模糊计数,否则不建议将set()与increment()和decrement()混合使用。
realm.executeTransaction(r -> { house.getGhosts().set(42); });
realm.executeTransaction { house!!.ghosts.set(42) }
由于MutableRealmInteger实例保留对其父对象的引用,因此,当您仍保留对MutableRealmInteger的引用时,这两个对象都无法进行垃圾回收。