Transforme une instance d'une classe en un @ protocole en Objective-C
-
03-07-2019 - |
Question
J'ai un objet (un UIViewController) qui peut être conforme ou non à un protocole que j'ai défini.
Je sais que je peux déterminer si l'objet est conforme au protocole, puis appelez 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'
Quel est le bon moyen d'éviter cet avertissement? Je n'arrive pas à convertir self.myViewController
en tant que MyProtocol
classe.
La solution
La bonne façon de faire est de faire:
if ([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
UIViewController <MyProtocol> *vc = (UIViewController <MyProtocol> *) self.myViewController;
[vc protocolMethod];
}
La conversion de type UIViewController <MyProtocol> *
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'un classe inconnue conforme à MyProtocol & ";
De cette manière, le compilateur vous donnera la vérification de type appropriée sur vc
. Le compilateur vous avertira uniquement si une méthode non déclarée sur UIViewController
ou <MyProtocol>
est appelée. id
ne doit être utilisé dans la situation si vous ne connaissez pas la classe / le type de l'objet à convertir.
Autres conseils
Vous pouvez le lancer comme ceci:
if([self.myViewController conformsToProtocol:@protocol(MyProtocol)])
{
id<MyProtocol> p = (id<MyProtocol>)self.myViewController;
[p protocolMethod];
}
Cela m'a jeté un peu aussi. En 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
) en même temps que le protocole souhaité.