Trasmetti un'istanza di una classe a un protocollo @ in Objective-C
-
03-07-2019 - |
Domanda
Ho un oggetto (un UIViewController) che può o meno essere conforme a un protocollo che ho definito.
So di poter determinare se l'oggetto è conforme al protocollo, quindi chiamare in sicurezza il metodo:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) {
[self.myViewController protocolMethod]; // <-- warning here
}
Tuttavia, XCode mostra un avviso:
warning 'UIViewController' may not respond to '-protocolMethod'
Qual è il modo giusto per prevenire questo avviso? Non riesco a trasmettere self.myViewController
come MyProtocol
classe.
Soluzione
Il modo corretto per farlo è fare:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
[vc protocolMethod];
}
Il tipo di cast UIViewController <MyProtocol> *
si traduce in " vc è un oggetto UIViewController conforme a MyProtocol " ;, mentre l'utilizzo di id <MyProtocol>
si traduce in " vc è un oggetto di un classe sconosciuta conforme a MyProtocol " ;.
In questo modo il compilatore ti darà il controllo del tipo corretto su vc
- il compilatore ti darà un avvertimento solo se viene chiamato un metodo non dichiarato su UIViewController
o <MyProtocol>
. id
dovrebbe essere usato nella situazione solo se non si conosce la classe / il tipo di oggetto che viene lanciato.
Altri suggerimenti
Puoi lanciarlo in questo modo:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
[p protocolMethod];
}
Anche questo mi ha gettato un po '. In Objective-C, il protocollo non è il tipo stesso, quindi è necessario specificare id
(o qualche altro tipo, come NSObject
) insieme al protocollo desiderato.