Swift 中的成员名称字符串

String as Member Name in Swift

我有一个字符串数组和一个 CoreData 对象,其中存储了一堆变量;字符串代表每个存储的变量。我想在列表中显示每个变量的值。但是,我找不到从 coredata 对象中获取所有变量的方法,因此我尝试使用以下代码。

ListView: View{
//I call this view from another one and pass in the object.
let object: Object
//I have a bunch of strings for each variable, this is just a few of them
let strings = ["first_name", "_last_name", "middle_initial" ...]


var body: some View{

List{

ForEach(strings){ str in
//Want to pass in string here as property name
object.str
//This doesn't work because string cannot be directly passed in as property name - this is the essence of my question.

}

}

}

}

所以如您所见,我只想传入字符串名称作为 CoreData 对象的成员名称。当我尝试上面的代码时,出现以下错误:'Object' 类型的值没有成员 'name' 和“.”后的预期成员名称。请告诉我如何将字符串作为 属性 名称传递。

Swift 是一种强类型语言,以 python/javascript 之类的方法进行迭代不太常见,也不推荐使用。 话虽如此,据我所知,您有三种方法可以解决这个问题。

首先,我建议将 CoreData 模型编码为字典 [String: Any][String: String] - 然后您可以保持所需的相同方法 - 迭代 属性 名称数组并按如下方式获取它们:

let dic = object.asDictionary()
ForEach(strings){ str in
//Want to pass in string here as property name
let propertyValue = dic[str]
//This doesn't work because string cannot be directly passed in as property name - this is the essence of my question.

}

确保遵守 Encodable 并拥有此扩展程序

extension Encodable {
  func asDictionary() throws -> [String: Any] {
    let data = try JSONEncoder().encode(self)
    guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
      throw NSError()
    }
    return dictionary
  }

其次,您可以对属性进行硬编码并 if/else/switch 在循环中覆盖它们

ForEach(strings){ str in
//Want to pass in string here as property name
switch str {
  case "first_name":
   // Do what is needed

}

}

第三,也是最后,你可以阅读并使用一种叫做反射的技术,这是最接近你想要实现的东西 link1 link2

CoreData 很大程度上基于 KVC(Key-Value 编码),因此您可以使用比字符串文字更可靠的键路径。

let paths : [KeyPath<Object,String>] = [\.first_name, \.last_name, \.middle_initial]

...

ForEach(paths, id: \.self){ path in
   Text(object[keyPath: path]))
}