【问题标题】:Reflection in swift 2Swift 2中的反射
【发布时间】:2016-01-01 03:44:48
【问题描述】:

我有一个班级用户:

import UIKit
import ObjectMapper


class User: NSObject, CustomStringConvertible, Mappable {

    var FirstName: NSString! ;
    var LastName: NSString! ;


    required init?(_ map: Map){

    }


    func mapping(map: Map) {

        FirstName <- map["FirstName"]
        LastName <- map["LastName"]

    }


    override var description:String {
        var s:String=""

  //USE REFLECTION TO GET NAME AND VALUE OF DATA MEMBERS      
        for var index=1; index<reflect(self).count; ++index {
            s += (reflect(self)[index].0 + ": "+reflect(self)[index].1.summary+"\t")
        }

        return s
    }
}

在 swift 1.2 中,我使用 reflect() 方法来获取所有数据成员及其名称和值的数组。

现在,在我更新到 swift 2 后,我收到以下错误:

'reflect' 不可用:调用'Mirror(reflecting:)' 初始化程序

通过一些试验,我能够通过以下方式获得数据成员的数量:Int(Mirror(reflecting: self).children.count),但仍然无法获得成员名称及其值。

我查看了以下资源:

  1. https://netguru.co/blog/reflection-swift
  2. http://nshipster.com/mirrortype/

更新 我在这里找到了答案:https://stackoverflow.com/a/32846514/4959077。但这并没有说明如何找出反射值的类型。如果值是 int 并且我们将其解析为 String 则它会给出错误。

【问题讨论】:

  • 这就是你要找的东西:stackoverflow.com/questions/32691894/… ?
  • .childrend 中的每个元素都有一个 .label 和 .value 如果你想获取类型,那么你可以获取 .value.dynamicType。欲了解更多信息,请参阅github.com/evermeer/EVReflection/blob/…
  • 另一个提示:您应该在进入循环之前调用一次反射。然后在循环中使用该变量。每次执行反射(自我)时,都会创建对象的快照。从理论上讲,对象甚至可能同时发生变化,从而导致不同的结果。

标签: swift reflection swift2


【解决方案1】:

我有一个解决方案,可以在给定任何继承自 NSObject 的类的情况下找到属性的名称和类型。

我在StackOverflow here上写了长篇解释,我的项目在here on Github

简而言之,你可以做这样的事情(但真的要查看代码 Github):

public class func getTypesOfProperties(inClass clazz: NSObject.Type) -> Dictionary<String, Any>? {
    var count = UInt32()
    guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
    var types: Dictionary<String, Any> = [:]
    for i in 0..<Int(count) {
        guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
        let type = getTypeOf(property: property)
        types[name] = type
    }
    free(properties)
    return types
}

【讨论】:

    【解决方案2】:

    您可以访问反射属性“标签”的名称、值和类型,如下所示:

    let mirror = Mirror(reflecting: SomeObject)
    
    var dictionary = [String: Any]() 
    for child in mirror.children {
        guard let key = child.label else { continue }
        let value: Any = child.value
    
        dictionary[key] = value
    
        switch value {
        case is Int: print("integer = \(anyValue)")
        case is String: print("string = \(anyValue)")
        default: print("other type = \(anyValue)")
        }
    
        switch value {
        case let i as Int: print("• integer = \(i)")
        case let s as String: print("• string = \(s)")
        default: print("• other type = \(anyValue)")
        }
    
        if let i = value as? Int {
            print("•• integer = \(i)")
        }
    }
    

    注意:根据问题跟进,显示了确定反射值类型的三种方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2014-12-02
      • 1970-01-01
      相关资源
      最近更新 更多