【问题标题】:Is there any point in querying realm on a background thread and resolving a ThreadSafeReference on the UI thread?在后台线程上查询领域并在 UI 线程上解析 ThreadSafeReference 是否有任何意义?
【发布时间】:2017-03-06 21:38:54
【问题描述】:

似乎最近添加了ThreadSafeReference 以帮助跨越线程边界。之前,根据我阅读的资料(可能并不详尽),建议只是在您打算使用结果的线程上查询领域;在 UI 线程上有效地查询它。

在后台线程上查询 Realm 是否有好处,或者解析 ThreadSafeReference 是否基本上再次运行查询?

这里是一个使用 RxSwift 的例子:

import RxSwift
import RealmSwift 


public static func getAllMyModels() -> Observable<Results<MyModel>>{

    return Observable<ThreadSafeReference<Results<MyModel>>>.create{
        observer in

        // using this queue in this example only
        DispatchQueue.global(qos: .default).async {

            let realm = try! Realm()
            let models = realm.objects(MyModel.self)
            let safe = ThreadSafeReference(to: models)

            observer.onNext(safe)
            observer.onCompleted()
        }

        return Disposables.create()
    }
    .observeOn(MainScheduler.instance) // push us back to the UI thread to resolve the reference
    .map{
        safeValue in

        let realm = try! Realm()
        let value = realm.resolve(safeValue)!
        return value
    }
    .shareReplayLatestWhileConnected()
}

通过查询某个后台线程并在 UI 线程上进行解析,我有什么收获吗?

【问题讨论】:

    标签: swift realm rx-swift


    【解决方案1】:

    似乎没有必要。根据文档,查询已经在后台线程上完成,只要您附加了通知块:

    一旦执行了查询,或者添加了通知块,结果就会随着领域中所做的更改而保持最新,并尽可能在后台线程上执行查询。 - https://realm.io/docs/swift/latest/#queries

    【讨论】:

      【解决方案2】:

      ast 的指导是正确的,但我挖掘了更多内容,并想发布一些额外内容以进一步确认他的答案。

      目前在 Realm 担任软件工程师的 kishikawa-katsumi 在 Realm 的公开 slack (https://realm-public.slack.com/archives/general/p1488960777001796) 中对这个问题做出了这样的回应:

      对于查询,在大多数情况下在 UI 线程中已经足够快了。如果您面临一些缓慢的复杂查询,您可以使用后台查询。 要在后台执行查询,请使用addNotificationBlock ()

      notificationToken = realm
          .objects(...)
          .filter(...)
          .addNotificationBlock { (changes) in
              // The query is executed in background.
              // When the query is completed, then call this block
              ...
          }
      

      使用addNotificationBlock(),查询在后台执行,当查询完成后,调用回调闭包。 所以ThreadSafeReference很少用在查询中。 ThreadSafeReference 用于将对象传递给另一个线程(例如,将其指定为查询条件或将其用作 API 请求的参数)。

      可以在此处找到有关从 GCD 线程(后台线程)订阅此块的其他信息,因为它需要运行循环。

      https://stackoverflow.com/a/41841847/1060314

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-06
        • 1970-01-01
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多