对象已被删除或无效的域

时间:2016-11-01 10:49:40

标签: swift realm

我让这个类继承自Object

class Location: Object {
    dynamic var id: String = ""
    dynamic var name: String = ""

    override class func primaryKey() -> String {
        return "id"
    }
}

此类在我的经理中用作实例,如下所示:

class LocationServiceAPI {

    fileprivate var _location: Location?
    var location: Location? {
        get {
            if _location == nil {
                let realm = try! Realm()
                _location = realm.objects(Location.self).first
            }
            return _location
        }
        set {
            let realm = try! Realm()

            if let newValue = newValue {
                // delete previous locations
                let locations = realm.objects(Location.self)
                try! realm.write {
                    realm.delete(locations)
                }

                // store new location
                try! realm.write {
                    realm.add(newValue, update: true)
                    _location = newValue
                }
            } else {
                let locations = realm.objects(Location.self)
                try! realm.write {
                    realm.delete(locations)
                }
            }
        }
    }
}

因此,每当我获得一个位置时,我删除旧位置(新旧位置可能相同)并将其替换为新位置,然后我使用newValue作为属性的新值{{1}但是每当我尝试访问_location时,它都会让我'对象已被删除或无效'。

我真的很困惑,因为location将保存从setter但不是领域传递的值!!

注意:如果我停止删除,那么它将正常工作。

2 个答案:

答案 0 :(得分:1)

如果某个对象已从Realm中删除,则会发生Object has been deleted or invalidated错误,但您随后尝试访问自删除之前代码挂起的该对象实例的存储属性。

您需要检查逻辑路径并确保无法删除位置对象,并且不会随后更新_location属性。没有提及删除您提供的示例代码中的对象,但是if let newValue = newValue代码行意味着如果您传入_location,则nil实际上不会被清除。

最后,可以通过调用_location.invalidated手动检查对象是否已从Realm中删除,因此如果这种情况发生了很多,那么在代码中包含一些额外的检查也是一个好主意。

答案 1 :(得分:0)

在不了解您的应用程序和设计选择的任何内容的情况下,看起来您正试图通过缓存location属性来避免经常读取/写入数据库。除非你使用大量LocationServiceAPI个对象,否则直接在数据库中实际读/写不应该是真正的性能损失,如下所示:

class LocationServiceAPI {

    var location: Location? {
        get {
            let realm = try! Realm()
            return realm.objects(Location.self).first
        }
        set {
           let realm = try! Realm()
           if let newValue = newValue {
              // store new location
              try! realm.write {
                  realm.add(newValue, update: true)
              }
           } else {
              // delete the record from Realm
              ...
           }
        }
    }
}

另外,我一般会避免长时间保持Realm对象,我不说这是不可能的,但总的来说它会导致你遇到的问题(特别是如果做多线程)。在大多数情况下,我宁愿从数据库中获取对象,使用它,更改它并尽快将其保存在数据库中。如果需要保留对DB中特定记录的引用,我宁愿保留id并在需要时重新获取它。