2016-07-06 7 views
-1

Swift 2.0でタイプ情報を分析しようとしていますが、それを静的構造に保存しようとしていますが、スタックしています。 最も有望なアプローチは、インスタンスに対してミラーを作成することです。これは、オンデマンドで一度だけ実行されます。デフォルトのinitを仮定し、ミラー要素のsubjectTypeを調べます。Swift 2.0タイプ解析のためのリフレクション

私の質問は以下のとおりです。

  • オプションの種類(例えばOptional<String>)をアンラップする方法。タイプとしてStringの部分を持っています。
  • 一般的な配列の型を決定する方法。 Array<Foo>

文字列を解析することは愚かであり、それはおそらく不可能です...配列に関連

その他の質問:要素の型を持っている場合は、どのように私は、新しいインスタンスを作成するのですか?

明確にする。タイプセーフであることを試みる関与するオブジェクトのタイプに関する情報を必要とする、または必要に応じて適切な変換を挿入する、マッパー(オブジェクトマッパー、jsonマッパー、ウィジェットマッパーなど)などのより高度なアルゴリズムのタイプ情報が必要です。

例外を発生させるべきでないInt?プロパティにマップする必要があるプロパティーIntを考えます。

コードは、これまでにすべての必要な情報を格納する必要がありPropertyDescriptor年代の配列が含まBeanDescriptorクラスを埋め

何かのように:

class PropertyDescriptor { 
    // instance data 

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

コードは、これまでのクラスを分析することである。

// 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 
    } 
} 

と呼ばれる機能

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

しかし、これは他の任意のクラスMoney?、および配列に関する他の情報をカバーしない。例えばArray<Money>、または私は配列型を検出するであろうし、ジェネリックアレイタイプを決定するためにどのように要素型

+1

をあなたが欲しいものを理解するのに苦労しています。あなたはいくつかのコードを投稿できると思いますか?あなたが持っているもの、欲しいもの、考えていることを示す擬似コードを示す何か? – solidcell

+0

質問を編集しました:-) –

答えて

-1

を決定しなければならないArray<Money?>、 "アレイ<はFoo>は"

this SO questionをご覧ください。 Array<AnyObject>として空の配列が見つかるので、現在空でない配列に対してのみ可能であることがわかります。

要素タイプがある場合、新しいインスタンスを作成するにはどうすればよいですか?

次の例は、オブジェクトをその型で初期化する方法を示しています。これは、(空の)init()コンストラクタがある限り、すべての型に対して実行できます。

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

なぜdownvote ?!どうか明らかにしてください。 –

0

あなたの質問を正しく理解していれば、クラスを分析して各プロパティのタイプを探したいですか?私は同じ必要性を持っていました。

私は、NSObjectから継承する任意のクラスを指定してプロパティの名前と型を見つけるソリューションを持っています。

私は StackOverflow hereに長い説明を書いた、と私のプロジェクトは、あなたがこのような何かを(本当にコードGitHubのチェックアウト)することができ要するに

here on 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

返事をありがとう。私は初めにそれを試しましたが、それはオプションで私を助けなかったし、異なるデータ型(数字のもの)でいくつかの奇妙な結果を示したので動作しませんでした。最後に、私はプロトタイプオブジェクトを作成し、ミラーを使用するために解決策をとどめました。配列とオプションの拡張と共に、私は興味深いもののほとんどを(実装されたプロトコルを除く)調べることができます。結果はここにあります:https://github.com/coolsamson7/inject/blob/master/Inject/beans/BeanDescriptor.swift –

+0

何がうまくいかないのですか? :) – Sajjon

+0

質問の回答がありますか? :-) –

関連する問題