J'ai un objet (un UIViewController) qui peut ou non être conforme à un protocole que j'ai défini.
Je sais que je peux déterminer si l'objet est conforme au protocole, puis appeler la méthode en toute sécurité:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)]) {
[self.myViewController protocolMethod]; // <-- warning here
}
Cependant, XCode affiche un avertissement:
warning 'UIViewController' may not respond to '-protocolMethod'
Quelle est la bonne façon d'éviter cet avertissement? Je n'arrive pas à lancer self.myViewController
en tant que classe MyProtocol
.
La bonne façon de procéder consiste à:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
[vc protocolMethod];
}
Le UIViewController <MyProtocol> *
type-cast se traduit par "vc est un objet UIViewController conforme à MyProtocol", alors que l'utilisation de id <MyProtocol>
se traduit par "vc est un objet d'une classe inconnue conforme à MyProtocol".
De cette façon, le compilateur vous donnera une vérification de type appropriée sur vc
- le compilateur ne vous donnera un avertissement que si une méthode n'est pas déclarée sur UIViewController
ou <MyProtocol>
est appelé. id
ne doit être utilisé dans la situation que si vous ne connaissez pas la classe/le type de l'objet en cours de conversion.
Vous pouvez le lancer comme ceci:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
[p protocolMethod];
}
Cela m'a un peu égaré aussi. Dans Objective-C, le protocole n'est pas le type lui-même, vous devez donc spécifier id
(ou un autre type, tel que NSObject
) avec le protocole souhaité.