objective-c protocols

objective c - Transmitir una instancia de una clase a @protocol en Objective-C



protocols (2)

Tengo un objeto (un UIViewController) que puede o no ajustarse a un protocolo que he definido.

Sé que puedo determinar si el objeto cumple con el protocolo, luego llamar al método de forma segura:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) { [self.myViewController protocolMethod]; // <-- warning here }

Sin embargo, XCode muestra una advertencia:

warning ''UIViewController'' may not respond to ''-protocolMethod''

¿Cuál es la forma correcta de prevenir esta advertencia? Parece que no puedo lanzar self.myViewController como una clase MyProtocol .


La forma correcta de hacer esto es hacer:

if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) { UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController; [vc protocolMethod]; }

El UIViewController <MyProtocol> * type-cast se traduce a "vc es un objeto UIViewController que se ajusta a MyProtocol", mientras que usar id <MyProtocol> traduce a "vc es un objeto de una clase desconocida que se ajusta a MyProtocol".

De esta forma, el compilador le dará la verificación de tipo adecuada en vc : el compilador solo le dará una advertencia si se llama a algún método que no se haya declarado en UIViewController o <MyProtocol> . id solo se debe usar en la situación si no se conoce la clase / tipo del objeto que se está emitiendo.


Puedes lanzarlo así:

if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) { id<MyProtocol> p = (id<MyProtocol>)self.myViewController; [p protocolMethod]; }

Esto también me afectó un poco. En Objective-C, el protocolo no es el tipo en sí mismo, por lo que debe especificar el id (o algún otro tipo, como NSObject ) junto con el protocolo que desee.