Swift 2中的反射

3

我有一个叫做User的类:

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,则会出现错误。


这是您要找的吗:http://stackoverflow.com/questions/32691894/reflect-property-value-on-swift-2-0? - Martin R
1
你的每个.children元素都会有一个.label和.value。如果你想获取类型,那么可以获取.value.dynamicType。更多信息请参见https://github.com/evermeer/EVReflection/blob/0879793e6d4ed5e554211eea7d654c7a0bfcdb82/EVReflection/pod/EVReflection.swift#L434-434。 - Edwin Vermeer
另一个提示:在进入循环之前,您应该先调用一次反射。然后在循环中使用该变量。每次执行reflect(self)时,都会创建对象的快照。理论上,对象甚至可能已经在此期间发生了更改,导致不同的结果。 - Edwin Vermeer
2个回答

3
您可以按照以下方式访问反射属性“label”的名称、值和类型:
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)")
    }
}

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

1

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

我在StackOverflow这里写了一篇详细的解释,我的项目可以在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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接