Клиент Firebase хранит копию всех данных, которые вы активно слушаете в памяти. После того, как последний прослушиватель отключится, данные будут сброшены из памяти.
Если вы включите жесткость диска в приложении Android Firebase с помощью:
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Клиент Firebase будет хранить локальную копию (на диске) всех данных, которые приложение недавно прослушивало.
. У вас есть следующие ValueEventListener
:
ValueEventListener listener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
// No-op
}
};
Когда вы добавите ValueEventListener
в местоположение:
ref.addValueEventListener(listener);
// OR
ref.addListenerForSingleValueEvent(listener);
Если значение местоположения находится в кеше локального диска, клиент Firebase немедленно вызовет onDataChange()
для этого значение из локального кеша. Если затем инициирует проверку с сервером, запрашивать какие-либо обновления для значения. Он может впоследствии снова вызвать onDataChange()
, если произошла смена данных на сервере с момента последнего добавления в кэш.
addListenerForSingleValueEvent
Когда вы добавляете прослушиватель событий одного значения в одно и то же место:
ref.addListenerForSingleValueEvent(listener);
Клиент Firebase (как и в предыдущей ситуации) сразу вызывает onDataChange()
для значения из локального дискового кэша. Он не еще раз вызовет onDataChange()
, даже если значение на сервере окажется другим. Обратите внимание, что обновленные данные по-прежнему будут запрашиваться и возвращаться при последующих запросах.
Это было рассмотрено ранее в . Как работает синхронизация Firebase с общими данными?
Лучшим решением является использование addValueEventListener()
вместо однозначного прослушивателя событий. Регулярный приемник значений получит как локальное событие, так и потенциальное обновление с сервера.
В качестве обходного пути вы также можете вызывать keepSynced(true)
в местах, где вы используете однозначный прослушиватель событий. Это гарантирует, что данные обновляются каждый раз, когда они меняются, что значительно повышает вероятность того, что ваш однозначный слушатель событий увидит текущее значение.
Короче говоря, это так, как указано в стандарте IEEE-754, на котором основаны операторы плавающей запятой Java .
Модель 754 поощряет надежные программы. Он предназначен не только для численных аналитиков, но и для пользователей электронных таблиц, систем баз данных или даже кофейников. Правила распространения для NaNs и бесконечностей допускают неосуществимые исключения для обращения в нуль. Аналогичным образом, постепенное недоисполнение поддерживает свойства ошибки в диапазоне точности.
Когда исключительные ситуации требуют внимания, их можно сразу проверить через ловушки или в удобное время с помощью флажков состояния. Ловушки могут использоваться для остановки программы, но неустранимые ситуации крайне редки. Простота остановки программы не является вариантом для встроенных систем или сетевых агентов. Чаще всего ловушки регистрируют диагностическую информацию или заменяют действительные результаты.
Флаги предлагают как предсказуемый поток управления, так и скорость. Их использование требует, чтобы программист знал об исключительных условиях, но флаг-липкость позволяет программистам откладывать обработку исключительных условий до тех пор, пока это не будет необходимо.
blockquote>
Это так, потому что именно это определил IEEE 754.
Подразделение по плавающей точке 0.0 дает NaN или +/- Inf, в зависимости от того, является ли числитель 0 или нет.
Разделение на целое число 0 не покрывается IEEE 754 и генерирует исключение - другого способа указания ошибки нет, потому что int
не может представлять NaN
или Inf
.
] Генерация исключения аналогична (программному обеспечению) INT
, генерируемому делением на ноль на микропроцессорах x86.
To Infinity and Beyond
class DoubleDivision {
public static void main(String[] args) {
System.out.println(5.0/0.0);
}
}
Вышеупомянутый код и упомянутые фрагменты дают infinity
.
Почему Java использует Double
s для представления десятичных знаков. Двоичный не может полностью представить число, он может представлять только приближение, и поэтому ни одна из них не может быть двойной.
Представьте число, невероятно близкое к нулю. Если вы знаете исчисление, представьте себе предел в ноль. Переменная будет приближаться к нулю до некоторого воображаемого крошечного расстояния, но никогда точно не будет равна. Вы можете себе это представить, верно? Ну, предположим, что для этого числа требуется так много точности для представления Java, он отказывается и называет его 0.0
, потому что у него нет хорошей альтернативы. Вот что здесь происходит. Любое регулярное число, деленное на супер близкое число к нулю, в основном, бесконечно. Попробуйте: 5 / (10^-100)
.
Также обратитесь к разделу: Специальные значения с плавающей запятой в Ошибки математики для получения дополнительной информации:)
Связанный вопрос: почему 1/0 дает ошибку, но 1.0 / 0/0 дает inf
UPDATE: INT
не имеет бесконечности и NaN
значение в наборе, тогда как float имеет бесконечность и значение NaN
. (Согласно стандартам IEEE 754, которые соответствуют java)
Когда есть деление на ноль, компьютер не может создать представление результата в виде числа. Компьютер должен сигнализировать о том, что результат не является числом.
Для значений с плавающей запятой он может выдавать специальное значение нечётного числа, поскольку есть 32-битные (для float
), и 64-битные (для double
) битовые шаблоны, которые не представляют число, и поэтому могут быть интерпретированы как не-число (NaN
).
Для целых значений с использованием общих двоичных чисел -компонента (как требуется Java), все 32-битные (для int
) и 64-битные (для long
) битовые шаблоны представляют собой число. Поэтому компьютер не может сообщить о проблеме с помощью дозорного устройства. Он должен каким-то образом сообщать о проблеме «вне диапазона». Выбрасывание исключения - это метод вне диапазона, выбранный для Java.