2016-07-06 9 views
-1

Ich versuche, Typinformationen in Swift 2.0 zu analysieren - und es in einer statischen Struktur zu speichern - aber stecke fest. Der erfolgversprechendste Ansatz besteht darin, einen Spiegel für eine Instanz zu erstellen - was einmal bei Bedarf gemacht werden würde, wobei eine Standardinitialisierung vorausgesetzt wird - und den subjectType der Spiegelelemente zu betrachten.Swift 2.0 Reflection für die Typanalyse

Meine Fragen sind:

  • Wie optionale Typen (z Optional<String>) auszupacken. Ich möchte den String Teil als einen Typ haben.
  • Wie generische Array-Typen, z.B. Array<Foo>.

Parsen der String ist albern und es ist wahrscheinlich nicht möglich ..

Andere Fragen zu Arrays bezogen werden: Wenn ein den Elementtyp haben, wie erstelle ich eine neue Instanz?

Um es klarer zu machen. Ich benötige die Typinformationen für höherwertige Algorithmen wie Mapper - Objektzuordnungen, Json-Mapper, Widget-Mapper usw. -, die Informationen über den Typ der involvierten Objekte, die versuchen, typsicher zu sein, oder bei Bedarf durch Einfügen geeigneter Konvertierungen benötigen.

Denken Sie an eine Eigenschaft Int, die einer Int?-Eigenschaft zugeordnet werden muss, die keine Ausnahme auslösen sollte.

Der Code bisher füllt eine BeanDescriptor Klasse, die ein Array von PropertyDescriptor ‚s enthält, die alle erforderlichen Informationen speichern soll

Etwas wie:

class PropertyDescriptor { 
    // instance data 

    var bean: BeanDescriptor; 
    var name: String; 
    var type: Any.Type; 
    var optional = false 
    // more data for arrays, e.g. elementType... 
    ... 
} 

-Code bisher eine Klasse zu analysieren ist:

// create a default instance 
let instance = create(); // we need a NSObject though! darn... 
let mirror = Mirror(reflecting: instance) 
if let displayStyle = mirror.displayStyle { 
    if displayStyle == .Class { 
    for case let (label?, value) in mirror.children { 
     let property = analyzeProperty(label, value: value) 

     properties[property.name] = property; 
     } // for 
    } 
} 

und die aufgerufene Funktion

func analyzeProperty(name : String, value: Any) -> PropertyDescriptor { 
    let mirror : Mirror = Mirror(reflecting: value) 
    var type = mirror.subjectType 
    var optional = false 

    // no way..this sucks! 

    if (type == String?.self) { 
     type = String.self // uhhhh 
     optional = true 
    } 
    else if ... // lots other literal types, ... 

    return PropertyDescriptor(bean: self, name: name, type: type, optional: optional) 
} 

Aber dies deckt andere optionale Klassen Money? sowie andere Informationen in Bezug auf Arrays, z. Array<Money> oder Array<Money?> wobei i einen Array-Typen erkennen würde und den Elementtyp

+1

Ich bin es schwer hat zu verstehen, was du willst. Denkst du, du könntest Code schreiben? Etwas was zeigt, was du hast, was du willst, und möglicherweise Pseudo-Code, der zeigt, was du denkst? – solidcell

+0

bearbeitet die Frage :-) –

Antwort

-1

, wie ermittelt generische Array-Typen bestimmen muss, z.B. "Array < Foo>"

Bitte werfen Sie einen Blick auf this SO question. Sie werden feststellen, dass es derzeit nur für nicht leere Arrays möglich ist, da leere Arrays als Array<AnyObject> gefunden werden.

Wenn ich den Elementtyp habe, wie erstelle ich eine neue Instanz?

Das folgende Beispiel zeigt, wie ein Objekt anhand seines Typs initialisiert wird. Dies kann für alle Typen gemacht werden, solange sie einen (leeren) init() Konstruktor haben.

let myType = ...//your code for getting the type 
let object: MyObject = myType.init() 
+0

Warum der Downvote ?! Bitte klären Sie. –

0

Wenn ich verstehe Ihre Frage richtig Sie wollen eine Klasse analysieren und die Art der einzelnen Eigenschaften finden? Ich hatte das gleiche Bedürfnis und ich habe es endlich funktioniert.

Ich habe eine Lösung, die den Namen und den Typ einer Eigenschaft für jede Klasse findet, die von NSObject erbt.

schrieb ich eine lange Erklärung auf StackOverflow here, und mein Projekt ist here on Github, erhältlich

Kurz man so etwas tun kann (aber wirklich den Code überprüfen 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 
} 
+0

danke für die Antwort. Ich habe das am Anfang versucht, aber es hat nicht funktioniert, weil es mir nicht mit Optionen geholfen hat und auch einige seltsame Ergebnisse mit verschiedenen Datentypen (numerische Sachen) gezeigt hat. Am Ende blieb ich bei der Lösung, um ein Prototyp-Objekt zu erstellen und einen Spiegel zu verwenden. Zusammen mit Erweiterungen zu Array und optional bin ich in der Lage, die meisten interessanten Dinge zu bestimmen (außer implementierte Protokolle). Sie können die Ergebnisse hier sehen: https://github.com/coolsamson7/inject/blob/master/Inject/beans/BeanDescriptor.swift –

+0

Was hat nicht funktioniert? :) – Sajjon

+0

Frage beantwortet? :-) –