【问题标题】:How does DispatchQueue.main.async store it's blocksDispatchQueue.main.async 如何存储它的块
【发布时间】:2020-09-10 14:46:22
【问题描述】:

我有一个类似这样的代码:

func fetchBalances() -> Observable<Result<[User], Error>> {

    Observable.create { observer in
        
        var dataChangeDisposable: Disposable?
        DispatchQueue.main.async {

            let realm = try! Realm()
            let user = realm.objects(UserData.self)
            dataChangeDisposable = Observable.collection(from: user)
                .map { $0.map { UserData.convert($0) } }
                .subscribe(onNext: {
                    observer.onNext(.success($0))
                })
        }

        return Disposables.create {
            dataChangeDisposable?.dispose()
        }
    }
}

我需要使用一些带有运行循环的线程来维护对 Realm 数据库的订阅(Realm 的限制)。现在我正在使用 DispatchQueue.main.async {} 方法,我注意到订阅一直处于活动状态, DispatchQueue.main 如何存储它提交的块,如果 Observable 销毁是否意味着我正在泄漏内存中的块?

【问题讨论】:

  • 不确定你在这里问的是什么,因为该代码绕过了 Realm,可能真的会导致很多其他问题; Realm 对象现在与 Realm 断开连接,它们不再延迟加载,user 是一个结果并将包含多个用户,而不仅仅是一个,并且该代码可能会导致对象线程问题。花点时间阅读Realm Notifications 上的领域文档。在这个用例中,maintain subscription 是什么意思。你能澄清一下这个问题吗?
  • @Jay 我的意思是,虽然我保持订阅状态,但我仍然从 Realm 获得更新,因此我得出结论 DispatchQueue.main 使我的块保持活动状态并将其存储在内部某个地方,以及问题我会因为 DispatchQueue.main 而在内存中泄露块吗?
  • 接受的答案专门解决了 Dispatch 队列的处理问题,这不是您的代码的真正问题。您不应该像那样创建对 Realm 数据库的“订阅”,并且您真的不想通过 Swift 构造处理 Realm 结果——这对于更大的数据集来说将是灾难性的,而且效率非常低。通读链接以了解如何正确使用领域通知,注意此 通知始终在它们最初注册的线程上传递。该线程必须有一个当前正在运行的运行循环

标签: ios swift realm rx-swift


【解决方案1】:

发送到调度队列的块在执行后立即被删除。它根本不会存储很长时间。

如果您的订阅“一直处于活动状态”,那是因为它没有得到妥善处理。这里可能发生的情况是发送到Disposables.create 的块在dataChangeDisposable 包含值之前被调用。

通过将代码更改为来测试我的假设:

return Disposables.create {
    dataChangeDisposable!.dispose()
}

如果您的应用因为 dataChangeDisposable 为 nil 而崩溃,那么这就是您的问题。

【讨论】:

  • 感谢您指出我的代码中的一个错误,我认为 Realm 需要 Run Loop 来一直传递通知,但是如果调度队列在执行后立即删除块,“泄漏”订阅如何从境界?
  • 我对如何使用Realm一无所知。我只是在回答有关您的订阅为何正确处置的问题。我建议您创建一个关于如何从 Realm 获取通知的新问题(或搜索该问题,因为它可能已经被回答了。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 2011-05-21
  • 2017-11-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多