繁体   English   中英

定期在Realm中保存对象

[英]Periodically save an object in Realm

我有一个名为Trip的Realm对象。 它存储用户运动的数据。

class Trip: Object {
    dynamic var id: Int = 0
    dynamic var startTimestamp: Int64 = 0
    dynamic var endTimestamp: Int64 = 0
    dynamic var distance: Double = 0.0
    dynamic var calories: Double = 0.0
    dynamic var averageSpeed: Double = 0.0
}

在视图控制器中,我保留了一个名为trip的类级变量。

fileprivate var trip: Trip?

每当用户开始旅程时,我都会初始化一个Trip对象并将其分配给该变量。

trip = Trip()

在用户的整个移动过程中,我不断使用数据更新此trip对象。

我需要每1分钟将此数据保存到Realm数据库中。 所以我运行一个计时器。

Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(save()), userInfo: nil, repeats: true)

它执行一个功能将此对象保存在后台线程中。

fileprivate func save() {
    do {
        DispatchQueue(label: "RealmBackgroundThread").async {
            autoreleasepool {
                let realm = try! Realm()
                try! realm.write {
                    realm.add(self.trip!, update: true)
                }
            }
        }

    } catch {

    }
}

到这里为止,一切正常。 问题是第一次保存后,当我尝试再次访问该trip对象时,它崩溃并显示以下错误。

libc ++ abi.dylib:以类型为realm :: IncorrectThreadException的未捕获异常终止:从错误线程访问的领域。

我认为发生这种情况是因为我打开一个新的Realm将该对象保存在后台线程中。 我知道Realm不是线程安全的。

但是我不确定如何解决这个问题。 保存后,如何继续使用相同的trip对象?

要引用Realm的文档中有关跨线程传递实例的信息

RealmResultsList实例或Object托管实例是线程限制的,这意味着它们只能在创建它们的线程上使用,否则会引发异常。

在您的情况下, self.tripObject子类的托管实例,您似乎同时从主线程和在save()方法中创建的串行分派队列中反复访问它。 重要的是要记住,对DispatchQueue.async的调用将导致您的代码在不同线程上执行,具体取决于Grand Central Dispatch的想法。 也就是说,两个连续的呼叫,例如……

DispatchQueue(label: "RealmBackgroundThread").async {
    // work
}

……通常会导致在两个不同线程上执行工作。

Realm关于跨线程传递实例的文档包含一个示例,该示例说明如何跨线程将线程安全引用传递给对象,并在目标线程上的Realm实例中解析该对象。

在您的情况下很难提供更具体的建议,因为我不清楚您要使用save()方法做什么以及为什么要在计时器上调用它的原因。 只能在写事务中修改托管Object实例(从Realm检索到的实例,或者已经添加到Realm的实例),因此对self.trip任何修改都需要在save()打开的写事务中执行save()以使其达到任何目的的方法。 对于使用计时器的方式,您需要将self.trip保留self.trip 托管对象,此时save()会使用Realm文件中的相同ID更新Trip实例。 为此,您需要使用Realm.create(_:value:update:)而不是Realm.add(_:update:) ,因为create不会像add那样将非托管实例转换为托管实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM