我正在从 Realm 对象中删除所有
@objc dynamic
注释,以使用更现代的 @Persisted
注释。
虽然它对很多代码都有好处,但我遇到了问题,其中之一与对象主键相关。 这是文档。让我们举个例子:
class MyObject: Object {
@objc public dynamic var uuid = ""
// many other properties...
override public static func primaryKey() -> String? {
"uuid"
}
}
这会变成这样:
class MyObject: Object {
@Persisted(primaryKey: true) @objc public var uuid: String
}
但是运行测试会输出此错误:
Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Primary Key for class 'MyObject' has been removed." UserInfo={Error Name=SchemaMismatch, NSLocalizedDescription=Migration is required due to the following errors:
- Primary Key for class 'MyObject' has been removed., Error Code=10}
注 1:需要
@objc
注释,因为该属性是从 Objective-C 代码访问的。我也在没有 @objc
注释的情况下测试了这个案例,结果是一样的。根据此问题/答案,这是可能的。
注 2:在这两种情况下(之前/之后),
uuid
都是这样初始化的:
override public required init() {
super.init()
let uuid = UUID().uuidString
}
这可能是因为架构中相关对象中存在另一个问题吗?比如我已经“翻译”了
@objc public private(set) dynamic var id: Int = 1
public var categoryList = List<PersistableIdentifiableObject>()
override public required init() {
super.init()
}
override public class func primaryKey() -> String? {
#keyPath(MyObject.id)
}
与
@Persisted(primaryKey: true) public private(set) var id: Int
@Persisted public var categoryList = List<PersistableIdentifiableObject>()
override public required init() {
super.init()
id = 1 // Yes, this is meant to be this way.
}
感谢您对此提供的任何帮助。
问题中的代码有一些问题,但让我尝试一下解释和答案。
所以这行不通
override public static func primaryKey() -> String? {
"uuid"
}
因为需要返回“uuid”,就像这样
override public static func primaryKey() -> String? {
return "uuid"
}
还要注意,在上面的例子中,primaryKey是一个String?所以让它成为一个 Int 工作
@Persisted(primaryKey: true) public private(set) var id: Int
并且不要对 Realm 对象执行此操作,因为它们需要方便的初始化,而不是覆盖。
override public required init() {
super.init()
--
现在 - 解决问题:
回到 @objc 的时代,这里是如何定义具有主键的对象。
class Dog: Object {
@objc dynamic var id = ""
override static func primaryKey() -> String? {
return "id"
}
}
请注意,primaryKey 函数返回主键属性的 name(不是它的值)并且是 可选
现在我们做同样的事情,确保它仍然是一个可选字符串。这将从 @obc 流到 Swift,无需迁移(假设属性相同)
class Dog: Object {
@Persisted(primaryKey: true) var id: String?
}
如果你希望主键是一个int,并且每次都初始化为1,代码如下
@Persisted(primaryKey: true) var id = 1
如果您想在实例化时使用提供的值初始化 Realm 对象,请在方便的 init 中执行此操作,确保调用 self.init 以让 Realm 将该对象初始化为 Realm 对象
class Dog: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name = ""
convenience init(withName: String) {
self.init()
self.name = withName
}
}
然后
let dog = Dog(withName: "Spot")