【问题标题】:Object has been deleted or invalidated realm对象已被删除或领域无效
【发布时间】:2016-11-01 10:49:39
【问题描述】:

我有这个类继承自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 作为属性 _location 的新值,但每当我尝试访问location 它给了我“对象已被删除或无效”。

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

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

【问题讨论】:

  • 如何删除丢弃的位置?第二个问题:你使用线程吗?
  • @bogdanf 我已经用删除部分更新了我的答案。
  • 所以你在整个应用程序中只使用了一个Location 对象(你删除了数据库中的所有Location 对象,所以我假设你只有一个)。为什么不将它存储在 NSUserDefaults 中,数据库真的不需要只存储一个对象 :-) 现在,如果你绝对需要将它保存在 Realm 中,只需像我一样直接从数据库中保存/检索它'已经在我的回复中向您展示了,真的,真的不需要将它缓存在 LocationServicesAPI 类的变量中。

标签: swift realm


【解决方案1】:

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

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

最后,可以通过调用_location.invalidated 手动检查对象是否已从领域中删除,因此如果这种情况经常发生,最好在代码中加入一些额外的检查。

【讨论】:

    【解决方案2】:

    在不真正了解您的应用程序和设计选择的情况下,您似乎试图通过缓存 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 对象保留更长的时间,我并不是说这是不可能的,但通常它会导致您遇到的问题(尤其是在执行多线程时)。在大多数情况下,我宁愿从数据库中获取对象,使用它,更改它并尽快将其保存回数据库中。如果需要保留对数据库中特定记录的引用,我宁愿保留 id 并在需要时重新获取它。

    【讨论】:

      猜你喜欢
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多