Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 354
JAL Avatar asked Mar 24 '16 14:03

JAL


1 Answers

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

like image 121
Joseph Lord Avatar answered Nov 08 '22 00:11

Joseph Lord