在后台线程中写入Realm后,主线程没有看到更新的数据

时间:2017-08-22 05:45:51

标签: ios swift multithreading realm

  1. 清除数据库。
  2. 进行API调用以获取新数据。
  3. 将从API检索到的数据写入后台线程中的数据库中。
  4. 从主线程上的数据库中读取数据并呈现UI。
  5. 在第4步中,数据应该是最新数据,但我们没有看到任何数据。

    // remark: all main thread shared a realm object
    DBManager.deleteAll()
    // call api success, get newdata
    DispatchQueue.global(qos: .background).async { 
        DBManager.initDBData(<newdata>)
        DispatchQueue.main.async {
            print("has data?????", DBManager.getBrands().count)
         }
     }
    
    // when write
    func write() {
        let realmBackgroud = try! Realm()
        try! realmBackgroud.write {}
     }
    

1 个答案:

答案 0 :(得分:9)

带有runloops的线程上的Realm实例,例如主线程update to the latest version of the data in the Realm file,因为通知被发布到其线程的runloop。在后台线程上提交写入事务与另一个线程的runloop接收到该通知之间存在时间窗口,并且由于CFRunLoop处理其调度队列相对于其通知源的顺序,这种情况并不罕见在提交写入事务之前立即执行主队列的dispatch_async,然后才能发送通知。

有几种方法可以解决这个问题:

  • 使用Realm的通知机制(如收集通知)对您在后台线程上所做的更改做出反应,而不是明确使用dispatch_async
  • 显式调用发送到主队列的块顶部的Realm.refresh(),使其自身进入最新版本,无论该线程是否有机会处理触发自动刷新的通知