2017-05-05 2 views
1

Ich bin eine Funktion erstellen, die eine Instanz eines Klassenobjekts nehmen und es in eine XML-Anfrage konvertieren, um an einen Webdienst gesendet werden. Um dies zu erreichen, verwende ich die Spiegelung, um die Schlüssel/Wert-Paare in der Klasse zu durchlaufen. In meinen Tests sehe ich, dass es gut funktioniert, mit einem Hauptproblem, keiner der vererbten Klassenparameter kommt zustande. Im folgenden Beispiel wird die Schleife dreimal für "descriptionText, modelNumber und serialNumber ausgeführt, Name und UUID werden nie erfasst. Gibt es eine Möglichkeit für mich, Spiegelung zu verwenden und alle Parameter der Basisklasse abzurufen, wie ? auch das Widget auch, wenn es ein besserer Weg, dies zu tun, bin ich ganz OhrSpiegeln nicht Basisklasse auf Swift 3

import UIKit 

class BaseObject: NSObject { 
    var name = String() 
    var uuid = String() 
} 

class Widget: BaseObject { 
    var descriptionText = String() 
    var modelNumber = String() 
    var serialNumber = String() 
} 

var widget1 = Widget() 

widget1.name = "Generic Widget" 
widget1.uuid = "A guid" 
widget1.descriptionText = "Class A Extra Larget Widget" 
widget1.modelNumber = "1234" 
widget1.serialNumber = "4321" 

let widgetMirror = Mirror(reflecting: widget1) 

for attr in widgetMirror.children { 
    print(attr.label!) 
} 

Antwort

1

Sie benötigen die superclassMirror: Mirror? Eigenschaft dafür verwenden, zum Beispiel:..

for attr in widgetMirror.superclassMirror!.children { 
    print(attr.label!) 
} 

Drucke die erwarteten Ergebnisse:

Name
Uuid


aktualisieren. Wenn Sie in diesem Laufen halten, fügen Sie diese MirrorErweiterung zu Ihrem Toolkit:

extension Mirror { 
    var allChildren: [Mirror.Child] { 
     var allChildren: [Mirror.Child] = [] 
     var mirror: Mirror! = self 
     repeat { 
      allChildren.append(contentsOf: mirror.children) 
      mirror = mirror.superclassMirror 
     } while mirror != nil 
     return allChildren 
    } 
} 

Verbrauch:

for attr in widgetMirror.allChildren { 
    print(attr.label!) 
} 
+1

Vielen Dank! Ich werde deine Antwort in 3 Minuten annehmen, du bist offensichtlich zu schnell für den Computer! – GED125

+0

@ GED125 haha ​​:-) –

1

Eine Teilantwort wurde bereits gebucht, aber hier ist ein Weg, um alles bis zu wickeln .

var mirror: Mirror? = Mirror(reflecting: widget1) 

repeat { 
    for (index, child) in mirror!.children.enumerated() { 
     print (child.label!) 
    } 

    mirror = mirror?.superclassMirror 
} while mirror != nil 

Ich dachte über ein bisschen mehr. Ich denke, das ist mehr Swifty.

extension Mirror { 

    var posterity: Children { 
     if let superclassMirror = superclassMirror { 
      return Children([children, superclassMirror.posterity].joined()) 
     } else { 
      return children 
     } 
    } 

} 

let widgetMirror = Mirror(reflecting: widget1) 

for child in widgetMirror.posterity { 
    print(child.label!) 
} 
+0

Nur ein kurzer Überblick: Der Name der 'Nachkommen' ist irreführend, da er nicht der gleichen * Semantik * der eingebauten 'Nachkommen' (_: _ :) 'Funktion folgt. Ich benutze 'allChildren', aber ich bin auch nicht glücklich :(Dinge zu benennen ist in der Tat schwierig, haha ​​... –

+0

@PauloMattos Yeah, ich habe nicht über 'Nachfahren (_: _ :)' nachgedacht und ich mag es nicht 'allChildren' entweder. Allerdings muss ich dieses Problem in StackOverflow nicht lösen, also werde ich nur dumm sein. Hoffe, dass Sie meine Änderung mögen. –