2015-12-22 10 views
9

Swiftで特定のプロトコルを実装しているすべてのクラスをリストする方法は?Swiftのプロトコルに準拠するすべてのクラスをリストする方法は?

たちは例があるとしましょう。ここでは

protocol Animal { 
    func speak() 
} 

class Cat:Animal { 
    func speak() { 
     print("meow") 
    } 
} 

class Dog: Animal { 
    func speak() { 
     print("Av Av!") 
    } 
} 

class Horse: Animal { 
    func speak() { 
     print("Hurrrr") 
    } 
} 

は私の(コンパイルではない)現在のアプローチです:

func getClassesImplementingProtocol(p: Protocol) -> [AnyClass] { 
    let classes = objc_getClassList() 
    var ret = [AnyClass]() 

    for cls in classes { 
     if class_conformsToProtocol(cls, p) { 
      ret.append(cls) 
     } 
    } 
    return ret 
} 

func objc_getClassList() -> [AnyClass] { 
    let expectedClassCount = objc_getClassList(nil, 0) 
    let allClasses = UnsafeMutablePointer<AnyClass?>.alloc(Int(expectedClassCount)) 
    let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>(allClasses) 
    let actualClassCount:Int32 = objc_getClassList(autoreleasingAllClasses, expectedClassCount) 

    var classes = [AnyClass]() 
    for i in 0 ..< actualClassCount { 
     if let currentClass: AnyClass = allClasses[Int(i)] { 
      classes.append(currentClass) 
     } 
    } 

    allClasses.dealloc(Int(expectedClassCount)) 

    return classes 
} 

しかし

getClassesImplementingProtocol(Animal.Protocol)または

getClassesImplementingProtocol(Animal)のいずれかを呼び出しますか、

Xcodeのエラーで

getClassesImplementingProtocol(Animal.self)

結果:期待される引数の型 '議定書' にタイプ(Animal.Protocol).TYPEの値を変換することはできません。

誰もこの仕事をしていますか?タイプのイントロスペクションのこの種は非常に遅くなる可能性があることを

@objc protocol Animal { 
    func speak() 
} 

class Cat:Animal { 
    @objc func speak() { 
    print("meow") 
    } 
} 

class Dog: Animal { 
    @objc func speak() { 
    print("Av Av!") 
    } 
} 

class Horse: Animal { 
    @objc func speak() { 
    print("Hurrrr") 
    } 
} 

注:あなたは、このようにあなたのコードに@objcを追加する必要があるタイプのイントロスペクションを取得するためのObjective-Cランタイムを使用しているので

+0

エラーが発生した行はありますか。 – luk2302

+0

これはあなたにとって参考になると思います:http://stackoverflow.com/questions/28124684/swift-check-if-generic-type-conforms-to-protocol –

答えて

4

+0

ありがとうブルーノ、それは動作します。パフォーマンスについては、私はちょうどそれを測定した:iPad3(私は遅いデバイスの中にあると見なします)では、getClassesImplementingProtocolの呼び出しで約115msかかりますが、iPhone6Sでは12msかかります。私にとっては、これはアプリの起動時に一度実行されるため、パフォーマンスは重大な問題ではありません。 – mixtly87

+0

私が期待したほど遅くないので、それは良いことです!私はあなたのために働いてうれしいです。 – ColGraff

+1

構造に似た何かを得る方法はありますか? –

関連する問題