RealmSwift 不保存属性

RealmSwift not saving properties

我有一个带有主键的简单用户对象

class User: Object {
@objc dynamic var userId: Int = 0
@objc dynamic var name: String = ""
@objc dynamic var email: String = ""
@objc dynamic var gender: String = ""
@objc dynamic var heightCm: Int = 0
@objc dynamic var heightFeet: Int = 0
@objc dynamic var heightInches: Int = 0
@objc dynamic var weightUnits: String = ""
@objc dynamic var heightUnits: String = ""

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

用户在 viewdidLoad 中实例化

    var user = User()

我将整个对象以其初始状态保存到 Realm,因此它由 Realm 管理

但是当我想将这样的个人 属性 写入 Realm - 它不会保存。

let realm = try! Realm()

  try! realm.write {
        user.heightCm = 175
    }
}

当我读回 属性 user.heightCm 它仍然是 0

如果我像这样保存整个对象,它就可以正常工作!

let realm = try! Realm()

try! realm.write {
  realm.add(user, update: .modified)
}

当只有一个 属性 发生变化时,我不想保存整个对象! 根据 Realm 最新文档,它应该可以工作

Realm documentation - Writes

但我无法让它工作。有什么想法吗?

好的,所以我找到了原因,虽然它在文档中 - 但有点误导。

对于遇到此问题的其他人。
跟你的对象有没有声明primaryKey有关!

因为我的对象有一个主键,所以单独的 属性 更新将不起作用,除非您指定与您尝试更新的对象关联的主键!我的主键为 1 的示例更新 OK

try! realm.write {
    realm.create(user.self, value: ["userId": 1, "heightCm": 175 ], update: .modified)
    // Note* other properties of the user object will remain unchanged
}

有趣的是,如果您尝试在未指定主键的情况下更新 属性,Realm 根本不会抛出任何错误。它只是不会更新 属性!

我发布这个答案是为了清晰和演示领域功能。

给定一个带有主键的人物对象

class PersonClass: Object {
    @objc dynamic var _id = 0
    @objc dynamic var name = "Jay"

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

实例化对象时,会默认主键为0,名字属性会是Jay

let person = PersonClass()

let realm = try! Realm()

try! realm.write {
    realm.add(person)
}

只要该对象没有超出范围,就可以更改名称。因此,让我们实例化同一个对象,但在

之后更改名称
let person = PersonClass()

let realm = try! Realm()

try! realm.write {
    realm.add(person)  //creates the Jay object
}

try! realm.write {
    person.name = "Cindy" // name of that managed object is now Cindy
}

您甚至可以从领域中读取对象,并在以后更新它。假设在您的代码的一部分中编写了 Jay PersonClass,但稍后您想将名称更新为 Leroy

let realm = try! Realm()

if let jayObject = realm.objects(PersonClass.self).filter("name == 'Jay'").first {
    try! realm.write {
        jayObject.name = "Leroy"
    }
}

运行 该代码的最终结果是最初名称为 Jay 的 PersonClass 对象被更新为新名称 Leroy

最后请注意,整数主键可能会很麻烦。我建议使用 ObjectId() class 生成唯一的主键。请参阅 Realm Documentation on Primary Keys 进一步阅读。