为什么我的链接对象没有领域?

Why do my linking objects not have a Realm?

在我的 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.realmNOT nil.

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

为了完整起见,Class X 是这样定义的:

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

Realm 版本 10.11.0,RealmDatabase 版本 11.1.1。

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

您可以将观察者添加到链接对象 属性 只要对象是托管的。让我从具有 DogClass 对象

的列表 属性 的 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)
    }
}

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

  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) 并在其中一个发生变化时触发。

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

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

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