领域 - 为什么在写入事务开始时触发通知块



我今天注意到 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

该规则很容易理解,我真的很好奇为什么开始写入事务会触发收集通知,而不是等到事务之后。

如果在上次

刷新 Realm 数据库和您开始写入事务之间,在不同的线程上进行写入操作,那么开始写入事务将隐式刷新 Realm 数据库。如果这导致任何更改,将立即发送任何适用的通知以通知您更改。

最新更新