6

Esiste un metodo -[NSObject conformsToProtocol:] per verificare se un protocollo specifico è adottato o meno. C'è qualche metodo per ottenere tutti i protocolli adottati per una classe, piuttosto che controllare una lista?Esiste un metodo di introspezione per ottenere tutti i protocolli adottati per una classe in Objective-C?

+1

Che cosa stai cercando di ottenere? –

+0

@ RichardJ.RossIII Ho spesso usato la conformità del protocollo in cui ho bisogno di qualche oggetto generale per poter selezionare e quindi inviare il lavoro a un target appropriato (ad es. Un UITableViewDataSource 'universale per poter scegliere una cella appropriata per un dato oggetto e poi impostare quell'oggetto); Ritengo che sia più gestibile e richieda meno ridenominazioni affinché il dispatcher trovi gli obiettivi appropriati tramite il runtime e quindi li interroga su ciò che si aspettano. Qualche idea su quel modello? – Tommy

risposta

11

C'è una soluzione più elegante: class_copyProtocolList()direttamente restituisce i protocolli adottati di una classe. Utilizzo:

Class cls = [self class]; // or [NSArray class], etc. 
unsigned count; 
Protocol **pl = class_copyProtocolList(cls, &count); 

for (unsigned i = 0; i < count; i++) { 
    NSLog(@"Class %@ implements protocol <%s>", cls, protocol_getName(pl[i])); 
} 

free(pl); 
+3

Si deve solo tenere a mente che questo elenco non contiene i protocolli adottati dalle superclassi, quindi - a seconda dell'elenco usato per questo elenco - potrebbe essere necessario risalire la catena della superclasse e chiamare di nuovo class_copyProtocolList(). –

+0

@MartinR Esattamente, esattamente, stavo davvero facendo fatica a capire perché questo non elencava un protocollo per "NSMutableDictionary" ... –

+0

è un'ottima risposta. Ha funzionato bene. Potrebbe non funzionare con ARC. ma funzionerà sicuramente con non ARC. Grazie. –

1

Si può provare objc_copyProtocolList

Vale a dire si ottiene l'elenco di tutti i protocolli e quindi si controlla se l'oggetto corrente è conforme a un protocollo specifico iterando l'elenco.

Edit:

H2CO3 soluzione è davvero meglio un

+0

Oppure 'class_copyProtocolList()'. –

+0

Come usarlo praticamente? –

+0

Vuoi dire che dovrei scrivere il codice? – Max

3

C'è esattamente NSObject +conformsToProtocol; la conformità del protocollo è dichiarata come parte dello @interface quindi non è specifica per ciascuna istanza. Quindi ad es.

if([[self class] conformsToProtocol:@protocol(UIScrollViewDelegate)]) 
    NSLog(@"I claim to conform to UIScrollViewDelegate"); 

Non c'è bisogno di discesa ai metodi di esecuzione di livello C a tutti, almeno per la prima parte della tua domanda. Non c'è niente in NSObject per ottenere un elenco di protocolli supportati.

Problemi correlati