Reflection in swift 2

被刻印的时光 ゝ 提交于 2020-01-01 16:43:10

问题


I have a class 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
    }
}

In swift 1.2, I was using reflect() method to get array of all the data members with their names and values.

Now, after I have updated to swift 2, I am getting the following error:

'reflect' is unavailable: call the 'Mirror(reflecting:)' initializer

With some trials, I was able to get the count of data members by this: Int(Mirror(reflecting: self).children.count), but still, I am unable to get the member name and its value.

I have looked into the following resources:

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

UPDATE I have found the an answer here: https://stackoverflow.com/a/32846514/4959077. But this doesn't tell how to find out the type of reflected value. If the value is int and we parse it into String then it gives error.


回答1:


You may access the reflected attribute "label" name, value and type as follows:

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)")
    }
}

Note: per the question followup, three approaches to determine the type of the reflected value are shown.




回答2:


I have a solution that finds the name and type of a property given any class that inherits from NSObject.

I wrote a lengthy explanation on StackOverflow here, and my project is available here on Github,

In short you can do something like this (but really check out the code 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
}


来源:https://stackoverflow.com/questions/32932447/reflection-in-swift-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!