2016-03-24 30 views
6

Utilizzando il runtime Objective-C, posso ottenere un elenco di tutti i @objc protocolli di un oggetto è conforme alle:Come si elencano i protocolli a cui è conforme un oggetto?

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

o tutti i protocolli di Objective-C caricati dal 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])])) 
} 

Ma nessuno di questi elenco qualsiasi protocollo Swift:

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 è 0 quando mi sarei aspettato per tornare sizeof(Protocol) * 2 (dal MyClass conforme allo Equatable e Hashable).

Esiste un'interfaccia esposta dal runtime per ottenere un elenco di protocolli a cui un oggetto è conforme?

risposta

4

Non è possibile. I protocolli Swift che non sono ObjC esistono solo al momento della compilazione e non esistono realmente sull'oggetto stesso (motivo per cui i loro metodi vengono inviati staticamente in base al tipo di variabile).

+0

Scusate per la mia maleducazione, ma questa risposta è insalatina di parole. Il compilatore sa. – Charlesism

+2

Il punto è che mentre il compilatore sa che il runtime no, l'informazione non viene catturata nel file binario compilato, quindi non è possibile interrogare l'oggetto particolare per informazioni. Non ho seguito gli sviluppi recenti sulla riflessione, quindi alcuni di questi potrebbero essere cambiati negli ultimi 18 mesi. –

+0

Saluti. Il tuo commento sarebbe una buona risposta :) Ho erroneamente interpretato la tua risposta originale come "swift non mantiene una db di conformità del protocollo" che non avrebbe senso alla luce dei controlli di compilazione di Swift. – Charlesism