A Realm oferece o MutableRealmInteger, um wrapper em torno de valores numéricos, para ajudar a sincronizar melhor as alterações numéricas em vários clientes.
Normalmente, incrementar ou decrementar um campo byte, short, int, ou long de um Objeto de Realm tem a seguinte aparência:
Leia o valor atual do campo.
Atualize esse valor na memória para um novo valor com base no incremento ou decremento.
Escreva um novo valor de volta ao campo.
Quando vários clientes distribuídos tentam fazer isso ao mesmo tempo, as atualizações que chegam aos clientes em diferentes ordens podem resultar em valores diferentes para clientes diferentes. MutableRealmInteger melhora isso traduzindo atualizações numéricas em operações de sincronização que podem ser executadas em qualquer ordem para convergir para o mesmo valor.
MutableRealmInteger os campos são apoiados por tipos numéricos tradicionais, portanto, nenhuma migração é necessária ao alterar um campo de byte, short, int ou long para MutableRealmInteger.
O exemplo a seguir demonstra um campo MutableRealmInteger que conta o número de fantasmas encontrados em uma casa mal-assassinada:
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) }
Importante
Os campos do contador devem ser finais
MutableRealmInteger é um objeto ativo como RealmObject, RealmResults e RealmList. Isso significa que o valor contido dentro do MutableRealmInteger pode mudar quando um Realm é gravado. Por esta razão os campos MutableRealmInteger devem ser marcados como finais em Java e val em Kotlin.
Uso
Os métodos counter.increment() e counter.decrement() os operadores garantem que os incrementos e decrementos de vários clientes distribuídos sejam agregados corretamente.
Para alterar um valor de MutableRealmInteger , chame increment() ou decrement() em uma transação de escrita:
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 }
Você pode atribuir um MutableRealmInteger um novo valor com uma chamada para contador.set() dentro de uma transação escrita.
Aviso
Redefinições do contador
Use o operador set() com muito cuidado. set() ignora os efeitos de quaisquer chamadas anteriores para increment() ou decrement(). Embora o valor de um MutableRealmInteger sempre converja entre dispositivos, o valor específico para o qual ele converge depende da ordem real em que as operações ocorreram. Não é recomendado misturar set() com increment() e decrement() , a menos que a contagem difusa seja aceitável.
realm.executeTransaction(r -> { house.getGhosts().set(42); });
realm.executeTransaction { house!!.ghosts.set(42) }
Como as instâncias MutableRealmInteger retêm uma referência ao objeto pai, nenhum dos objetos pode ser coletado como lixo enquanto você ainda reter uma referência ao MutableRealmInteger.