2011-01-10 7 views
12

in Objective-C quando si dichiara una variabile di istanza è possibile verificare se è conforme a un protocollo di assegnazione in fase di compilazione modo:Verifica se un oggetto è conforme ai due protocolli separati in Objective-C

id <MyProtocol> variable; 

È possibile verificare se un oggetto assegnato alla variabile è conforme a due protocolli separati in fase di compilazione? Come in:

id <MyProtocol, MyOtherProtocol> variable; 

So che posso fare runtime controllo utilizzando conformsToProtocol: e respondsToSelector et al, (cosa che faccio prima di poter realmente utilizzando l'oggetto per una maggiore sicurezza), e ho potuto scrivere il mio metodo setter che fa l'assegno , ma mi piacerebbe sapere al momento della compilazione.

+0

Does not 'id variabile;' lavoro? Almeno si compila senza problemi ... – Vladimir

+0

Non sono al momento al computer che posso controllare, ma mi piacerebbe sapere per una discussione che sto avendo con un collega. – Jasarien

risposta

12

I pensano che la cosa migliore è di utilizzare il proprio codice:

id <MyProtocol, MyOtherProtocol> variable; 

E prima di chiamare un metodo, verificare se la variabile risponde a ciò che si desidera chiamare :

if ([variable respondsToSelector:@selector(aMethod:)]) { 
    [variable aMethod:nil]; 
} 

Dal Objective-C è un linguaggio dinamico, basta dichiarare il protocollo variabile non può assicurare che sia conforme al protocollo. Generalmente genera avvisi quando si costruisce.

+0

Grazie, ho solo dovuto sapere che la sintassi era valida e funzionava. – Jasarien

3

Non è sempre possibile verificare la conformità del protocollo in fase di compilazione poiché un oggetto di tipo (non qualificato) id è sempre un oggetto valido dal punto di vista del compilatore. Per esempio,

id<P1> p1; 
id<P2> p2; 
id p0; 

// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>' 
p1 = p2; 

// no compiler warning 
p0 = p2; 
p1 = p0; 

Detto questo, <P1, P2> vi darà avvisi nel caso in cui l'oggetto non è conforme a entrambi i protocolli se che si possono sapere a tempo di compilazione:

id<P1> p1; 
id<P2> p2; 
id<P1, P2> p12; 
id<P1, P2> q12; 
id p0; 

p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>' 
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>' 
p12 = q12; // no compiler warning 

// no compiler warning 
p0 = p1; 
p12 = p0; 
47

Sì, quella sintassi è corretta.

Il modo corretto per verificare se un oggetto è conforme a un protocollo è di fare questo:

if ([myObj conformsToProtocol:@protocol(MyProtocol)]) { 
    //conformance! 
} 

noti che questo funziona sia come un metodo di istanza e un metodo di classe.

Se per qualche strano motivo non è possibile utilizzare il conformsToProtocol:, si può cadere fino al livello di esecuzione:

#import <objc/runtime.h> 

Protocol * p = objc_getProtocol("MyProtocol"); 
if (class_conformsToProtocol([myObj class], p)) { 
    //conformance! 
}