2017-02-02 3 views
0

Я заметил сегодня, что блоки уведомлений Realm запускаются при начале транзакции записи. Интуитивно я бы подумал, что , заканчивающийся, транзакция записи вызовет уведомления о коллекции с изменениями, которые только что произошли, но сегодня я обнаружил сбой в моем коде, вызванный тем, что блок уведомлений вызывается, когда начинается транзакция записи.Realm - Почему блоки уведомлений срабатывают при начале транзакции записи?

Соответствующих кадров стека до моего обращения уведомления вызываются:

frame #17: 0x0000000102535b98 Realm`RLMNotificationToken* RLMAddNotificationBlock<realm::Results>(this=0x00000001742974f0, changes=0x000000016fdf9de0, err=<unavailable>) block_pointer, bool)::'lambda'(realm::CollectionChangeSet const&, std::exception_ptr)::operator()(realm::CollectionChangeSet const&, std::exception_ptr) const + 608 at RLMCollection.mm:345 
    frame #18: 0x0000000102535700 Realm`realm::CollectionChangeCallback::Impl<RLMNotificationToken* RLMAddNotificationBlock<realm::Results>(objc_object*, realm::Results&, void (objc_object*, RLMCollectionChange*, NSError*) block_pointer, bool)::'lambda'(realm::CollectionChangeSet const&, std::exception_ptr)>::after(this=0x00000001742974e8, change=0x000000016fdf9de0) + 56 at collection_notifications.hpp:157 
    frame #19: 0x000000010248723c Realm`realm::CollectionChangeCallback::after(this=0x000000016fdf9dd0, c=0x000000016fdf9de0) + 64 at collection_notifications.hpp:122 
    frame #20: 0x0000000102487198 Realm`auto realm::_impl::CollectionNotifier::after_advance(this=0x000000016fdf9f90, lock=0x000000016fdf9ef0, callback=0x0000000103b62520)::$_9::operator()<std::__1::unique_lock<std::__1::mutex>, realm::_impl::CollectionNotifier::Callback>(std::__1::unique_lock<std::__1::mutex>&, realm::_impl::CollectionNotifier::Callback&) const + 156 at collection_notifier.cpp:326 
    frame #21: 0x0000000102479780 Realm`void realm::_impl::CollectionNotifier::for_each_callback<realm::_impl::CollectionNotifier::after_advance()::$_9>(this=0x00000001049d3e18, fn=0x000000016fdf9f90)::$_9&&) + 236 at collection_notifier.cpp:367 
    frame #22: 0x0000000102479688 Realm`realm::_impl::CollectionNotifier::after_advance(this=0x00000001049d3e18) + 28 at collection_notifier.cpp:315 
    frame #23: 0x000000010247ba3c Realm`realm::_impl::NotifierPackage::after_advance(this=0x000000016fdfa5e8) + 352 at collection_notifier.cpp:474 
    frame #24: 0x00000001026c8de4 Realm`void (anonymous namespace)::advance_with_notifications<realm::_impl::transaction::begin(context=0x0000000174221480, sg=0x0000000104020200, func=0x000000016fdfa540, notifiers=0x000000016fdfa5e8)::$_1>(realm::BindingContext*, realm::SharedGroup&, realm::_impl::transaction::begin(realm::SharedGroup&, realm::BindingContext*, realm::_impl::NotifierPackage&)::$_1&&, realm::_impl::NotifierPackage&) + 1152 at transact_log_handler.cpp:674 
    frame #25: 0x00000001026c8958 Realm`realm::_impl::transaction::begin(sg=0x0000000104020200, context=0x0000000174221480, notifiers=0x000000016fdfa5e8) + 56 at transact_log_handler.cpp:702 
    frame #26: 0x00000001024de620 Realm`realm::_impl::RealmCoordinator::promote_to_write(this=0x0000000103b0e108, realm=0x0000000103b0e498) + 328 at realm_coordinator.cpp:741 
    frame #27: 0x00000001026766b4 Realm`realm::Realm::begin_transaction(this=0x0000000103b0e498) + 552 at shared_realm.cpp:483 
    frame #28: 0x000000010262df3c Realm`::-[RLMRealm beginWriteTransaction](self=0x00000001740a9fc0, _cmd="beginWriteTransaction") + 48 at RLMRealm.mm:437 

В конкретном случае использования в моем коде, один из моих уведомлений обратных вызовов создает новый набор RLMResults для отображения в таблице и добавляет уведомление блокировать его. Добавление блока уведомлений повышает ожидаемое исключение в этом случае: Cannot create asynchronous query while in a write transaction.

Это правило легко понять, мне действительно интересно узнать, почему начало транзакции записи инициирует уведомления о сборах, а не ждет до завершения транзакции.

+0

Начиная транзакцию записи автоматически обновляет версию Realm в потоке, на котором вы начинаете транзакцию, поэтому имеет смысл, чтобы коллекции были уведомлены об увеличении версии Realm. Я думаю, что это обычно происходит, только если вы выполняете транзакции записи в потоке пользовательского интерфейса, что обычно не является хорошей практикой. (возьмите это с солью, уведомления об уведомлениях еще не установлены на Android, так что я могу ошибаться) – EpicPandaForce

ответ

0

Если запись была сделана в другом потоке между тем, когда Realm был последним обновленным, и когда вы начинаете транзакцию записи, начало транзакции записи будет неявно обновлять Realm в первую очередь. Если это приведет к чему-либо изменению, любые соответствующие уведомления будут отправлены немедленно, чтобы уведомить вас об этом изменении.

+0

Требуется ли отправка уведомлений _inside_ транзакции записи, а не до ее начала? Ваше объяснение определенно имеет смысл, но я все равно ожидаю, что это произойдет в другом порядке. 1) обновить, 2) уведомления об отправке, 3) ввести транзакцию вместо 3, 1, 2. – LeffelMania

+0

Отправка их за пределы транзакции записи может привести к тому, что другой поток будет писать, пока отправляются уведомления. В идеальном случае, что поток будет получать блокировку записи, отправлять уведомления, а затем начать транзакцию, но в настоящее время это невозможно из-за проблем с реализацией. –

+0

Получил это. Спасибо за ваши ответы! <3 Царство. – LeffelMania

Смежные вопросы