Vérifier si une méthode existe

111

Existe-t-il un moyen de tester si une méthode existe dans Objective-C?

J'essaye d'ajouter un garde pour voir si mon objet a la méthode avant de l'appeler.

teepusink
la source
Il y a aussi la question de savoir si c'est la bonne approche en premier lieu, puisque les classes Objective-C peuvent répondre à des sélecteurs qu'elles n'ont pas déclarés (via - forwardInvocation:).
Donal Fellows

Réponses:

189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}
KennyTM
la source
72

Il y a aussi le message statique instancesRespondToSelector: (SEL) selector Vous l'appeleriez comme ceci:

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

ou comme ça:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

Cela peut être utile si vous souhaitez appeler un constructeur ou un autre en fonction de cela (je veux dire, avant d'avoir l'instance elle-même).

Ricard Pérez del Campo
la source
1
Quelle est la différence entre instancesRespondToSelector et respondsToSelector?
CReaTuS le
1
La principale différence est que l'un est un message d'instance (pour tester si un message d'instance déterminé existe) tandis que l'autre est un message de classe (pour tester si un message de classe déterminé existe).
Ricard Pérez del Campo le
1
+1 Pour [MyClass instancesRespondToSelector]. J'en avais besoin dans une méthode de création d'init: lorsque le sous-classement est peut-être nécessaire d'appeler une méthode super init au lieu d'autres (obsolètes), car self n'a pas encore été créé et respondsToSelector retournera toujours NON.
LightMan
12

Utilisez respondsToSelector:. De la documentation :

respondsToSelector:

Renvoie une valeur booléenne qui indique si le récepteur implémente ou hérite d'une méthode capable de répondre à un message spécifié.

- (BOOL)respondsToSelector:(SEL)aSelector

Paramètres
aSelector - Un sélecteur qui identifie un message.

Valeur de retour
YES si le récepteur implémente ou hérite d'une méthode qui peut répondre à un sélecteur , sinon NO.

Carl Norum
la source
10

Vous recherchez des répondsToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

Comme Donal le dit, ce qui précède vous dit que foo peut certainement gérer la réception du sélecteur de barre. Cependant, si foo est un proxy qui transmet la barre à un objet sous-jacent qui recevra le message de barre, alors respondsToSelector: vous dira NON, même si le message sera transféré à un objet qui répond à la barre.

Frank Shearar
la source
1

La vérification des sélecteurs avec respondsToSelector est normalement réservée aux méthodes déléguées. Vous ne devriez pas utiliser forwardInvocation ou proxy pour les méthodes de délégué. Si vous devez utiliser respondsToSelector dans d'autres situations, vous voudrez peut-être vous assurer qu'il n'y a pas de manière plus appropriée de concevoir votre programme.

Eric
la source