JAL
JAL

Reputation: 42449

How do I list the Protocols an Object Conforms to?

Using the Objective-C runtime, I can get a list of all of the @objc protocols an object conforms to:

let obj = NSObject()

var pc: UInt32 = 0
let plist = class_copyProtocolList(object_getClass(obj), &pc)

print("\(obj.dynamicType) conforms to \(pc) protocols")

for i in 0 ..< Int(pc) {
    print(String(format: "Protocol #%d: %s", arguments: [i, protocol_getName(plist[i])]))
}

or all of the Objective-C protocols loaded by the runtime:

var allProtocolCount: UInt32 = 0

let protocols = objc_copyProtocolList(&allProtocolCount)

print("\(allProtocolCount) total protocols")

for i in 0 ..< Int(allProtocolCount) {
    print(String(format: "Protocol #%d: %s", arguments: [i, protocol_getName(protocols[i])]))
}

But neither of these list any Swift protocols:

func == (lhs: MyClass, rhs: MyClass) -> Bool {
    return lhs.value == rhs.value
}

class MyClass: Equatable, Hashable {

    var value: Int
    var hashValue: Int {
        return value
    }

    init(value: Int) {
        self.value = value
    }
}

var count: UInt32 = 0;

let strProtocols = class_copyProtocolList(MyClass.self, &count) // 0x0000000000000000

strProtocols is 0 when I would expect it to return sizeof(Protocol) * 2 (since MyClass conforms to Equatable and Hashable).

Is there an interface exposed by the runtime to get a list of protocols an object conforms to?

Upvotes: 7

Views: 1844

Answers (1)

Joseph Lord
Joseph Lord

Reputation: 6504

You can't. Swift protocols that are not ObjC ones only exist at compile time and do not really exist on the object itself (which is why their methods are dispatched statically based on the type of the variable).

Upvotes: 4

Related Questions