2011-01-10 8 views
12

en Objective-C cuando se declara una variable de instancia se puede comprobar si se ajusta a un protocolo sobre la asignación en tiempo de compilación como tan:Comprobación de si un objeto se ajusta a dos protocolos separados en Objective-C

id <MyProtocol> variable; 

¿Es posible verificar si un objeto asignado a la variable cumple con dos protocolos separados en tiempo de compilación? Como en:

id <MyProtocol, MyOtherProtocol> variable; 

Sé que puedo hacer en tiempo de ejecución comprobación usando conformsToProtocol: y respondsToSelector et al, (que debo hacer antes de utilizar el objeto para mayor seguridad), y pude escribir mi propio método de selección que hace el cheque , pero me gustaría saberlo en tiempo de compilación.

+0

no 'id variables;' ¿trabajo? Al menos compila sin problemas ... – Vladimir

+0

Actualmente no estoy en una computadora que pueda verificar, pero me gustaría saber si tengo una conversación con un colega. – Jasarien

Respuesta

12

I que lo mejor es utilizar su propio código:

id <MyProtocol, MyOtherProtocol> variable; 

Y antes de llamar a un método, comprobar si la variable responde a lo que desea llamar :

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

Desde Objective-C es un lenguaje dinámico, simplemente se declara la variable de protocolo no puede asegurar que se cumpla con el protocolo. Principalmente generará advertencias cuando construyas.

+0

Gracias, solo necesitaba saber que la sintaxis era válida y funcionaba. – Jasarien

3

No siempre se puede verificar la conformidad del protocolo en tiempo de compilación porque un objeto de tipo (no calificado) id es siempre un objeto válido desde la perspectiva del compilador. Por ejemplo,

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; 

Dicho esto, <P1, P2> le dará advertencias en caso de que el objeto no se ajusta a los protocolos si que se pueden conocer en tiempo de compilación:

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í, esa sintaxis es correcta.

La forma correcta para comprobar si un objeto es conforme a un protocolo es hacer esto:

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

Tenga en cuenta que esto funciona tanto como un método de instancia y un método de clase.

Si por alguna extraña razón no se puede utilizar el conformsToProtocol:, que puede caer hasta el nivel de ejecución:

#import <objc/runtime.h> 

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