【问题标题】:Why do my linking objects not have a Realm?为什么我的链接对象没有领域?
【发布时间】:2021-07-28 22:36:38
【问题描述】:

在我的 iOS 应用中,出现以下异常:

'Linking objects notifications are only supported on managed objects.'

当我尝试添加观察者块时:

y.xxx.observe { ... }

到这样定义的属性:

class Y: Object {
    ...
    let xxx = LinkingObjects(fromType: X.self, property: "y")
    ...
}

我相信这意味着y.xxx 没有Realm,而且我确实可以在调试器中看到y.xxx.realmnil。但是,y.realm 不是 nil

如果我要链接的对象有 Realm,那么链接对象怎么可能没有 Realm?

为了完整起见,这是 X 类的定义方式:

class X: Object {
    ...
    @Persisted var y: Y?
    ...
}

Realm 版本 10.11.0,RealmDatabase 版本 11.1.1。

上下文:我正处于将最初用 ObjC 编写的应用程序迁移为纯 Swift 的最后阶段。这意味着切换到 Swift 版本的 Realm。我在以前版本的应用程序中没有遇到过这个问题,除了它使用非常旧版本的 Realm 框架并且 Realm 对象是在 ObjC 中定义的之外,它的代码库基本相同。

【问题讨论】:

  • 查看this answer 了解更多信息。
  • @Jay 谢谢,但我认为这个答案在这里不适用。我相信我了解链接对象应该如何工作,正是由于它们的自动/计算性质,我无法理解如何会出现对象具有领域但其链接对象没有的情况。
  • 我想我看错了你的帖子。您可以按照您的要求做,所以我提供了一个示例作为答案。

标签: ios realm


【解决方案1】:

只要对象是受管理的,您就可以将观察者添加到链接对象的属性中。让我从拥有 DogClass 对象的 List 属性的 PersonClass 开始设置

class PersonClass: Object {
    @objc dynamic var _id = ObjectId.generate()
    @objc dynamic var name = "Jay"
    
    let dogList = List<DogClass>()

    override static func primaryKey() -> String? {
        return "_id"
    }
}

然后我们的 DogClass 与 PersonClass 对象具有反向关系

class DogClass: Object {
    @objc dynamic var _id = ObjectId.generate()
    @objc dynamic var name = ""

    let linkingOwners = LinkingObjects(fromType: PersonClass.self, property: "dogList")

    override static func primaryKey() -> String? {
        return "_id"
    }
}

然后假设我们想要观察 Spot 的 linkingOwners - Jay 和 Cindy 之前都将 Spot 添加到他们的 dogList 中

let spot = realm.objects(DogClass.self).filter("name == 'Spot'").first!
self.peopleToken = spot.linkingOwners.observe { changes in
    switch changes {
    case .initial(let dogs):
        print("  spots owners have been loaded")

    case .update(_, let deletions, let insertions, let modifications ):
        print("  something changed in spots owners")

    case .error(let error):
        print(error.localizedDescription)
    }
}

运行这部分代码将其输出到控制台并将观察者添加到链接对象

  spots owners have been loaded

然后,让我们更改其中一个所有者属性

    let jay = realm.objects(PersonClass.self).filter("name == 'Jay'").first!
    try! realm.write {
        jay.name = "Jay, Spots owner"
    }

最后一段代码会将其输出到控制台

  something changed in spots owners

上面的代码创建了一个PersonClass对象和一个DogClass对象,对象是反比关系。然后代码添加一个观察者 linkingObjects (PersonClass) 并在其中一个发生变化时触发。

【讨论】:

  • 我很欣赏你的努力,但是 a) "@objc dynamic var"(事实证明,"LinkingObjects(fromType: ") 是旧的符号样式,并且 b) 即使这样,它没有回答我为什么会遇到异常的问题。
【解决方案2】:

原来链接对象现在必须像这样声明:

class Y: Object {
    ...
    @Persisted(originProperty: "y") var xxx: LinkingObjects<X>
    ...
}

我不确定我在问题中使用的声明样式是否仍然应该有效,以及这是否是一个错误,但使用新样式可以消除异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 2018-03-04
    • 1970-01-01
    相关资源
    最近更新 更多