【问题标题】:Access list property in Realm migration领域迁移中的访问列表属性
【发布时间】:2020-01-06 19:40:40
【问题描述】:

我正在尝试访问迁移块中的 List<String> 属性。

我的数据库对象如下所示:

@objcMembers
public class Foo: Object {
    let bar: List<String> = .init()
}

在我的迁移块中,我尝试访问 bar,但似乎无法正确访问:

static func migrateFoo(_ migration: RealmSwift.Migration) {
    migration.enumerateObjects(ofType: Foo.className()) { old, _ in
        let test = old?["bar"] as? List<String>
        let test2 = old?["bar"] as? [String]
        let test3 = old?["bar"]
    }
}

testtest2 都是 niltest3 的输出显示如下:

(lldb) po test3
▿ Optional<Any>
  - some : List<string> <0x600001fb5f80> (
    [0] someContent
)

我需要将test3 投射到什么位置才能访问该列表?

编辑

我想访问bar 属性中的元素,因此我认为将迁移对象的bar 属性转换为List&lt;String&gt;,毕竟这是数据类型就足够了。最后我想要的是这样的:

for element in test {
    print(element) // `element` should be a `String` here
}

【问题讨论】:

  • 这可能源于原语是 Realm 中的二等公民...如果可能,请尝试使用 String 属性创建一个包装类。
  • @OscarApeland 这也许是可能的。不幸的是,更改bar 的类型会导致很多其他问题:/

标签: ios swift realm realm-migration


【解决方案1】:

我不知道您尝试做的全部范围是什么,但该问题的具体答案是:

let test = [ old!["bar"] ]

编辑

OP 增加了一些额外的信息。目标是能够访问 bar List 属性中的值。下面是一些快速的代码,它遍历该列表并将索引和对象(作为字符串)输出到控制台。

migration.enumerateObjects(ofType: Foo.className()) { oldItem, newItem in
    let dynamicBarList = oldItem?.dynamicList("stringList")
    if let list = dynamicBarList {
        let myArray = list._rlmArray
        let lastIndex = myArray.count - 1

        for index in 0...lastIndex {
            let object = myArray.object(at: index)
            let value = "\(object)" //make the NSTaggedPointerString a String
            print(index, value)
        }
    }
}

【讨论】:

  • 我不确定我是否遵循。我想访问bar 属性列表中的元素。使用您的方法,我会将Any 对象包装到一个数组中?
  • 啊..好的。可能需要在问题中添加更多内容,以便更清楚。不确定您在做什么.. 迁移到新对象或只需要访问元素。我会尽快更新。
  • 我的错,我会更新我的问题以澄清这一点。感谢您的帮助!
  • @ShitakeOishii 好的,更新了答案。这将使您能够访问 foo 列表中的数据。
  • @Jay let supportedDocumentTypes = existingCompanyObject.dynamicList("supportedDocumentTypes") let supportedDocumentTypesArray = supportedDocumentTypes._rlmArray for index in 0...supportedDocumentTypesArray.count - 1 { if let value = supportedDocumentTypesArray.object(at:指数)作为? Int { ... } } 访问supportedDocumentTypesArray.count 时,我返回“Swift 运行时失败:算术溢出”。就我而言,我有一个 List 需要在迁移中访问
【解决方案2】:

您可以将您的列表转换为 DynamicObjects 列表(允许对象的非类型化 getter 和 setter 的对象接口):

if let old = old?["bar"] as? List<DynamicObject> {
    for i in 0..<old.count {
        let p = old[i]
        print(p) // someContent
    }
}

【讨论】:

  • 我会尝试一下。
  • 这实际上引发了一个异常:无法将类型“NSTaggedPointerString”(0x7fff87a8a270)的值转换为“RealmSwift.DynamicObject”(0x10ec94fe8)。
  • 嗯。这很有趣。测试的时候,我的list是RealmObjects的集合,没有问题。当我使用字符串列表进行测试时,我得到了同样的错误。但是,如果您通过下标访问字符串,则没有问题...我不完全确定这是为什么,但我将对其进行调查,如果我弄清楚了,我会回复您。与此同时,我已经更新了我的答案。
  • @ShitakeOishii 问题是 Realm 如何处理列表中的原语。他们是一种二手公民,所以在某些情况下,您最好创建一个类来实际保存列表中的字符串,如下所示; class MyStringClass: Object { objc dynamic var my_string = "" } 然后将该类的对象存储在列表中。那么这个答案中的代码就可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
相关资源
最近更新 更多