2015-12-22 35 views
9

Làm thế nào để liệt kê tất cả các lớp thực hiện một giao thức đã cho trong Swift?Làm thế nào để liệt kê tất cả các lớp phù hợp với giao thức trong Swift?

Giả sử chúng ta có một ví dụ:

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

Đây là hiện tại của tôi (không biên dịch được) Cách tiếp cận:

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 
} 

Nhưng khi gọi hoặc

getClassesImplementingProtocol(Animal.Protocol) hoặc

getClassesImplementingProtocol(Animal) hoặc

getClassesImplementingProtocol(Animal.self)

kết quả trong lỗi Xcode: không được chuyển đổi loại giá trị (Animal.Protocol) .Loại đối số dự kiến ​​'Giao thức'.

Có ai quản lý việc này không?

+0

Lỗi nào xảy ra? – luk2302

+0

Tôi nghĩ điều này có thể hữu ích cho bạn: http://stackoverflow.com/questions/28124684/swift-check-if-generic-type-conforms-to-protocol –

Trả lời

4

Vì bạn đang sử dụng thời gian chạy Objective-C để có được những mẫn kiểu bạn cần phải thêm @objc mã của bạn theo cách này:

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

Lưu ý rằng loại này loại mẫn có thể rất chậm.

+0

Cảm ơn Bruno, nó hoạt động. Về hiệu suất, tôi chỉ cần đo nó: trên iPad3 (mà tôi coi là một trong các thiết bị chậm) phải mất ca 115ms cho một cuộc gọi 'getClassesImplementingProtocol', trong khi trên iPhone6S phải mất 12ms. Đối với tôi, điều này được thực hiện một lần khi khởi động ứng dụng, vì vậy hiệu suất không phải là vấn đề quan trọng. – mixtly87

+0

Không chậm như tôi mong đợi, vì vậy đó là một điều tốt! Tôi vui vì nó đã làm việc cho bạn. – ColGraff

+1

Có cách nào để có được một cái gì đó tương tự với cấu trúc? –

Các vấn đề liên quan