Transmitir una instancia de una clase a un @protocol en Objective-C
-
03-07-2019 - |
Pregunta
Tengo un objeto (un UIViewController) que puede o no ajustarse a un protocolo que he definido.
Sé que puedo determinar si el objeto se ajusta al protocolo y luego llamar al método con seguridad:
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 evitar esta advertencia? Parece que no puedo transmitir self.myViewController
como una clase MyProtocol
.
Solución
La forma correcta de hacer esto es hacer:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
[vc protocolMethod];
}
La conversión de tipo UIViewController <MyProtocol> *
se traduce en " vc es un objeto UIViewController que se ajusta a MyProtocol " ;, mientras que usar id <MyProtocol>
se traduce en " vc es un objeto de un clase desconocida que se ajusta a MyProtocol " ;.
De esta forma, el compilador le dará una verificación de tipo adecuada en vc
- el compilador solo le dará una advertencia si se llama a cualquier método que no se haya declarado en UIViewController
o <MyProtocol>
. id
solo debe usarse en la situación si no conoce la clase / tipo del objeto que se está lanzando.
Otros consejos
Puedes lanzarlo así:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
[p protocolMethod];
}
Esto también me arrojó un poco. En Objective-C, el protocolo no es el tipo en sí mismo, por lo que debe especificar id
(o algún otro tipo, como NSObject
) junto con el protocolo que desee.