Swift Language                
            反射
        
        
            
    サーチ…
構文
- ミラー(反映:インスタンス)//ミラーを初期化して、対象を反映させます
- mirror.displayStyle // Xcodeのプレイグラウンドに使用される表示スタイル
- mirror.description //このインスタンスのテキスト表現。「 CustomStringConvertible 」を参照してください。
- mirror.subjectType //反射される対象のタイプを返します
- mirror.superclassMirror //反映されているサブジェクトのスーパークラスのミラーを返します
備考
- 一般的な備考:
 Mirrorは、Swiftのオブジェクトのイントロスペクションに使用されるstructです。その最も顕著なプロパティはchildren配列です。使用可能なケースの1つは、 Core Data構造体をシリアル化することです。これは、 structをNSManagedObject変換することによって行われます。 
- ミラーの基本的な使用方法備考:
 Mirrorのchildrenプロパティは、Mirrorインスタンスが反映しているオブジェクトの子オブジェクトの配列です。 childオブジェクトには、 labelとvalue 2つのプロパティがありvalue 。例えば、子供はtitleというtitleとGame of Thrones: A Song of Ice and Fireの値を持つプロパティであるかもしれません。 
ミラーの基本的な使用法
ミラーの対象となるクラスを作成する
class Project {
    var title: String = ""
    var id: Int = 0
    var platform: String = ""
    var version: Int = 0
    var info: String?
}
実際にミラーの対象となるインスタンスを作成する。ここでは、Projectクラスのプロパティに値を追加することもできます。
let sampleProject = Project()
sampleProject.title = "MirrorMirror"
sampleProject.id = 199
sampleProject.platform = "iOS"
sampleProject.version = 2
sampleProject.info = "test app for Reflection"
以下のコードは、Mirrorインスタンスの作成を示しています。ミラーのchildrenプロパティはAnyForwardCollection<Child>ここで、 Childはサブジェクトのプロパティと値のtypealiasタプルです。 Childはlabel: String持っていたlabel: Stringとvalue: Any 。 
let projectMirror = Mirror(reflecting: sampleProject)
let properties = projectMirror.children
print(properties.count)        //5
print(properties.first?.label) //Optional("title")
print(properties.first!.value) //MirrorMirror
print()
for property in properties {
    print("\(property.label!):\(property.value)")
}
上のforループのXcodeでPlaygroundまたはConsoleに出力します。
title:MirrorMirror
id:199
platform:iOS
version:2
info:Optional("test app for Reflection")
Xcode 8 Beta 2でPlaygroundでテスト済み
クラスのプロパティの型と名前をインスタンス化せずに取得する
 Swiftクラスの使用Mirrorは、特定のクラスのインスタンスの名前 、 値 、 型 (Swift 3: type(of: value) 、Swift 2: value.dynamicType )をvalue.dynamicTypeする場合に機能します 。 
もしクラスから継承する場合はNSObjectは、メソッドを使用することができますclass_copyPropertyList一緒property_getAttributes そのインスタンスを持たずに - 名前とクラスのプロパティの種類を見つけるために。私はGithubのプロジェクトを作成しましたが、ここにコードがあります: 
func getTypesOfProperties(in 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
}
func getTypeOf(property: objc_property_t) -> Any {
    guard let attributesAsNSString: NSString = NSString(utf8String: property_getAttributes(property)) else { return Any.self }
    let attributes = attributesAsNSString as String
    let slices = attributes.components(separatedBy: "\"")
    guard slices.count > 1 else { return getPrimitiveDataType(withAttributes: attributes) }
    let objectClassName = slices[1]
    let objectClass = NSClassFromString(objectClassName) as! NSObject.Type
    return objectClass
}
    
   func getPrimitiveDataType(withAttributes attributes: String) -> Any {
        guard let letter = attributes.substring(from: 1, to: 2), let type = primitiveDataTypes[letter] else { return Any.self }
        return type
    }
 primitiveDataTypesは、属性文字列内の文字を値型にマッピングするディクショナリです。 
let primitiveDataTypes: Dictionary<String, Any> = [
    "c" : Int8.self,
    "s" : Int16.self,
    "i" : Int32.self,
    "q" : Int.self, //also: Int64, NSInteger, only true on 64 bit platforms
    "S" : UInt16.self,
    "I" : UInt32.self,
    "Q" : UInt.self, //also UInt64, only true on 64 bit platforms
    "B" : Bool.self,
    "d" : Double.self,
    "f" : Float.self,
    "{" : Decimal.self
]
    
   func getNameOf(property: objc_property_t) -> String? {
        guard let name: NSString = NSString(utf8String: property_getName(property)) else { return nil }
        return name as String
    }
 NSDate (Swift3: Date )、 NSString (Swift3: String ?)、 NSNumberなどのNSObjectから継承するすべてのプロパティのNSObject.Typeを抽出できますが、 Any型のストアです(メソッドによって返されたDictionaryの値の型)。これは、Int、Int32、Boolなどのvalue typesの制限に起因します。これらの型はNSObjectから継承しないので、Int- Int.self .selfを呼び出すとNSObject.Typeが.selfれず、 Any型が返されます。したがって、このメソッドはDictionary<String, Any>?返しますDictionary<String, Any>? Dictionary<String, NSObject.Type>?なくDictionary<String, NSObject.Type>? 。 
このメソッドは次のように使用できます。
class Book: NSObject {
    let title: String
    let author: String?
    let numberOfPages: Int
    let released: Date
    let isPocket: Bool
    init(title: String, author: String?, numberOfPages: Int, released: Date, isPocket: Bool) {
        self.title = title
        self.author = author
        self.numberOfPages = numberOfPages
        self.released = released
        self.isPocket = isPocket
    }
}
guard let types = getTypesOfProperties(in: Book.self) else { return }
for (name, type) in types {
    print("'\(name)' has type '\(type)'")
}
// Prints:
// 'title' has type 'NSString'
// 'numberOfPages' has type 'Int'
// 'author' has type 'NSString'
// 'released' has type 'NSDate'
// 'isPocket' has type 'Bool'
また、 AnyをNSObject.TypeにキャストしようとすることもできますNSObject 、 NSObjectから継承したすべてのプロパティで成功します。次に、標準==演算子を使用して型をチェックできます。 
func checkPropertiesOfBook() {
    guard let types = getTypesOfProperties(in: Book.self) else { return }
    for (name, type) in types {
        if let objectType = type as? NSObject.Type {
            if objectType == NSDate.self {
                print("Property named '\(name)' has type 'NSDate'")
            } else if objectType == NSString.self {
                print("Property named '\(name)' has type 'NSString'")
            }
        }
    }
}
このカスタム==演算子を宣言した場合: 
func ==(rhs: Any, lhs: Any) -> Bool {
    let rhsType: String = "\(rhs)"
    let lhsType: String = "\(lhs)"
    let same = rhsType == lhsType
    return same
}
このようにvalue typesの型の型をチェックすることさえできます: 
func checkPropertiesOfBook() {
    guard let types = getTypesOfProperties(in: Book.self) else { return }
    for (name, type) in types {
        if type == Int.self {
            print("Property named '\(name)' has type 'Int'")
        } else if type == Bool.self {
            print("Property named '\(name)' has type 'Bool'")
        }
    }
}
 制限事項このソリューションは、 value typesがオプションである場合は機能しません。 NSObjectのサブクラスで次のようにプロパティを宣言した場合: var myOptionalInt: Int?上記のコードでは、 class_copyPropertyListメソッドにオプションの値型が含まれていないため、そのプロパティは見つかりません。