【问题标题】:Can I set values for a Swift object properties using mirroring?我可以使用镜像设置 Swift 对象属性的值吗?
【发布时间】:2015-09-30 23:11:49
【问题描述】:

现在我可以使用Mirror 类型检查对象的变量。但是我可以使用镜像为我的变量设置值吗?或者也许还有另一种纯 Swift 方式?

例如,我想从 JSON 创建一个对象(Swift struct)。是否可以不继承 NSObject 并为此使用 Objective-C 函数?

【问题讨论】:

    标签: json swift swift2 mirror mirroring


    【解决方案1】:

    这是我目前能做的最好的事情。它仍然缺少将 mirrorObject 转换回其泛型类型。仅供参考,这是使用 SwiftyJSON

    func convertToObject<T>(json: JSON, genericObject: T) -> T {
        let mirroredObject = Mirror(reflecting: genericObject)
    
        for (_, var attr) in mirroredObject.children.enumerate() {
            if let propertyName = attr.label as String! {
                attr.value = json[propertyName]
                print(propertyName)
                print(attr.value)
            }
        }
        // Figure out how to convert back to object type...
    }
    

    【讨论】:

    • @Randex 弄清楚如何转换回对象类型是困难的部分。除非您想为您创建的每种类型进行自定义扩展。在 swift 4 中有可解码和可编码。这些可以动态地做到这一点。
    • 这只是错误:'Mirror.Children' 类型的值(又名'AnyCollection, value: Any)>')没有成员'enumerate'
    • 如果你让它枚举它工作,但设置 attr.value 对对象属性值没有影响
    【解决方案2】:

    这是一个老问题,但答案对我不起作用。

    我必须将我的 swift 对象更改为 NSObject 才能使事情正常工作,并且还要具有动态属性。

    在我的例子中,我使用 pod Marshal 来反序列化数据。

     class MyClass: NSObject, Unmarshaling
      {
           // @objc dynamic make property available for NSObject
           @objc dynamic var myProperty: String?
    
           required init(object: MarshaledObject) throws {
              super.init()
    
              initUsingReflection(object: object)
            }
    
            func initUsingReflection(object: MarshaledObject) {
              let mirror = Mirror(reflecting: self)
    
              // we go through children
              for child in mirror.children {
                guard let key = child.label else {
                  continue
                }
    
                // This line is here to get the value from json, in my case I already know the type I needed
                let myValue: String = try! object.value(for: key)
    
                // The trick is here, setValue only exist in NSObject and not in swift object.
                self.setValue(myValue, forKey: key)
              }
           }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 2020-04-23
      • 2010-11-24
      • 2011-07-08
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多