Convertir una instancia de una clase a un protocolo @en Objective-C


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, luego llamar con seguridad al método:

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 manera correcta de prevenir esta advertencia? Parece que no puedo lanzar self.myViewController como una clase MyProtocol.

Author: Ford, 2009-03-06

2 answers

La forma correcta de hacer esto es hacer:

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

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

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

 156
Author: Nick Forge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-21 21:08:00

Puedes lanzarlo así:

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

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

 55
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-15 11:09:29