可选 Int 属性 在迁移期间包含 nil 而不是零

Optional Int property contains nil instead of zero during migration

我正在尝试从以下模型执行 Realm.IO 迁移:

public class RealmBuddy: Object {
    dynamic var id = 0
    let contactId = RealmOptional<Int>()
    dynamic var name = ""
    let topics = List<RealmTopic>()

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

以下内容:

public class RealmBuddy: Object {
    dynamic var id = 0
    dynamic var contactId: String? = nil
    dynamic var name = ""
    let topics = List<RealmTopic>()

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

如您所见,唯一的变化是 contactId 的类型:optional Int 应该转换为 optional String。我是这样实现的:

if (oldSchemaVersion < 1) {
    migration.enumerate(RealmBuddy.className()) { oldObject, newObject in
        if let contactId = oldObject!["contactId"] as? Int {
            newObject!["contactId"] = "\(contactId)"
        }
    }
}

但是,我发现在迁移之后我没有 contactId(即 nil 值)的实体现在的 contactId 等于“0”字符串。似乎 oldObject!["contactId"] returns 0 而不是 nil.

我没有找到任何关于如何执行这个简单任务的信息或示例,所以我不确定我 retrieve/cast 值是否正确(也尝试转换为 RealmOptional<Int>),所以我决定在 github 上提交问题之前先在这里询问一下。 这是错误还是预期行为?如果是预期行为,如何正确获取值?

PS: 我的项目是开源的,因为我是 iOS 的新手,开发它是为了自学,所以我把它推到了repo where the issue can be easily reproduced (please note that it is in migration_issue branch). I also made a unit test 使用现有 .realm 文件,该文件在测试期间迁移到新模式。希望能有所帮助。

PPS: 我尝试了 0.102.1 和 0.103.1 版本的库。

PPPS: 有人提到 Realm Browser 在我的示例 .realm 文件中不显示任何值为 nil 的 contactId。我认为这只是领域浏览器的问题,所以我在单独的分支中制作了另一个 unit test 来证明旧数据库 具有 零值。

当我在 Realm 浏览器中打开 default-v0.realm 时,我没有看到任何包含空 contactId 的行。如果您期望有一个,那么问题出在最初填充 Realm 的代码中,而不是迁移代码中。

这是一个错误。参见 https://github.com/realm/realm-cocoa/pull/3643。已在 0.103.2 中修复。

Optional properties of scalar types were getting the wrong Objective-C type code, leading to the dynamic accessors taking the non-optional code path. This resulted in nil values being returned as 0.