ios – Realm – 无法使用现有主键值创建对象

我有一个对象有许多狗的人.应用程序有单独的页面,它只显示狗和其他页面显示人的狗

我的模型如下

class Person: Object {
    dynamic var id = 0
    let dogs= List<Dog>()

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

class Dog: Object {
    dynamic var id = 0
    dynamic var name = ""

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

我有人存储在Realm中.人有详细页面,我们取,并显示他的狗.如果狗已经存在,我会更新该狗的最新信息并将其添加到人的狗列表中,否则创建新狗,保存并将其添加到人员列表中.这适用于coredata.

// Fetch and parse dogs
if let person = realm.objects(Person.self).filter("id =\(personID)").first {
    for (_,dict): (String,JSON) in response {
        // Create dog using the dict info,my custom init method
        if let dog = Dog(dict: dict) {
            try! realm.write {
                // save it to realm
                realm.create(Dog,value:dog,update: true)
                // append dog to person
                person.dogs.append(dog)
            }
        }
    }
    try! realm.write {
        // save person
        realm.create(Person.self,value: person,update: true)
    }
}

在尝试用他的狗更新人时,领域会抛出异常
无法使用现有主键值创建对象

解决方法

这里的问题是,即使你正在创建一个全新的Realm Dog对象,你实际上并没有将它保存到数据库中,所以当你调用append时,你正试图添加第二个副本.

当你调用realm.create(Dog,value:dog,update:true)时,如果数据库中已存在具有该ID的对象,则只需使用您创建的dog实例中的值更新现有对象,但是那个狗实例仍然是一个独立的副本;它不是数据库中的Dog对象.您可以通过检查dog.realm是否等于nil来确认这一点.

所以当你调用person.dogs.append(dog)时,因为dog还没有在数据库中,所以Realm会尝试创建一个全新的数据库条目,但是因为已经有一个带有该ID的狗而失败了.

如果要将该狗对象附加到某个人,则需要查询Realm以检索引用数据库中条目的正确狗对象.值得庆幸的是,使用主键支持的Realm对象非常简单,因为您可以使用Realm.object(ofType:forPrimaryKey :)方法:

if let person = realm.object(ofType: Person.self,forPrimaryKey: "id") {
    for (_,JSON) in response {
        //Create dog using the dict info,my custom init method
        if let dog = Dog(dict: dict)
        {
            try! realm.write {
                //save it to realm
                realm.create(Dog,value: dog,update: true)
                //get the dog reference from the database
                let realmDog = realm.object(ofType: Dog.self,forPrimaryKey: "id")
                //append dog to person
                person.dogs.append(realmDog)
            }
        }
    }
    try! realm.write {
        //save person
        realm.create(person .self,value: collection,update: true)
    }
}

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...