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.