2017-02-02 12 views
0

今日、書き込みトランザクションが開始されるときに、レルム通知ブロックがトリガーされることに気付きました。直感的に私は、と書かれたトランザクションは、変更が発生したばかりのコレクション通知をトリガーすると思っていましたが、書き込みトランザクションが開始されたときに通知ブロックが呼び出された結果、レルム - 書き込みトランザクションの開始時に通知ブロックがトリガーされるのはなぜですか?

関連するスタックフレームの私の通知処理が起動される前に:私のコード内の特定の使用例では

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 

を、私の通知コールバックの1がテーブルに表示するRLMResultsの新しいセットを作成し、通知を追加ブロックする。通知ブロックを追加すると、その場合に予想される例外が発生します。Cannot create asynchronous query while in a write transaction

このルールは分かりやすいですが、書き込みトランザクションを開始すると、トランザクションの後まで待つのではなく、コレクション通知がトリガーされるのはなぜか不思議です。

+0

書き込みトランザクションを開始すると、トランザクションを開始しているスレッドのRealmバージョンが自動的に最新バージョンにバンプされるため、Realmバージョンの増加についてコレクションに通知することは意味があります。私は、一般的には良い方法ではないUIスレッドで書き込みトランザクションを実行する場合にのみこれが一般的に起こると思います。 (塩の穀物でこれを取る、コレクションの通知はまだAndroidにはないので、私は間違っている可能性があります) – EpicPandaForce

答えて

0

レルムが最後にリフレッシュされたときと書き込みトランザクションを開始するときの間に別のスレッドで書き込みが行われた場合、書き込みトランザクションの開始は暗黙のうちにレルムを最初にリフレッシュします。この結果、何か変更が生じた場合は、適用通知がすぐに送信され、変更が通知されます。

+0

通知は、開始前とは違って、書き込みトランザクションの_inside_に派遣する必要がありますか?あなたの説明は間違いありませんが、私はまだそれが別の順序で起こることを期待しています。 1)リフレッシュ、2)ディスパッチ通知、3)3,1,2の代わりにトランザクションを入力する。 – LeffelMania

+0

書込みトランザクションの外にそれらを送信すると、通知が送信されている間に別のスレッドが書込みを行う可能性があります。理想的には、スレッドが書き込みロックを取得し、通知を送信してからトランザクションを開始することが理想的ですが、実装上の問題により現在は不可能です。 –

+0

入手しました。あなたのお返事ありがとう! <3王国。 – LeffelMania

関連する問題