web-dev-qa-db-fra.com

Équivalent à la méthode de classe de-respondsToSelector:

Existe-t-il une méthode de classe équivalente à -respondsToSelector:?

Quelque chose comme +respondsToSelector:?

La raison pour laquelle je demande, c'est parce qu'en implémentant -respondsToSelector: au niveau de la classe, j'obtiens un avertissement du compilateur: "found '-correspondsToSelector:' au lieu de '+ respondsToSelector:' in protocol (s)".

Le code ressemble à ceci:

Class <SomeProtocol> someClass = [someInstance class];

if ([someClass respondsToSelector:@selector(someSelector:)]) {
    someVar = [someClass someSelector:someData];
}
67
firstresponder

Mettre à jour après avoir vu votre modification:

Un objet de classe répond très bien à respondsToSelector:, Comme vous le savez probablement. Dans une application de test, je peux effectuer les deux opérations suivantes sans aucun avertissement du compilateur:

NSLog(@"Responds to selector? %i", [MyObject respondsToSelector:@selector(respondsToSelector:)]);
NSLog(@"Responds to selector? %i", [[MyObject class] respondsToSelector:@selector(respondsToSelector:)]);

Cependant, vous avez déclaré un protocole sur votre variable, il suppose donc que l'objet de classe vers lequel vous pointez implémente ces méthodes. La solution la plus simple serait de convertir someClass en id pour appeler respondsToSelector:. Une solution quelque peu plus propre serait de déclarer votre propre @protocol Qui déclare +respondsToSelector:(SEL)selector, puis de déclarer someClass comme suit:

Class<SomeProtocol, ClassRespondingToSelector> someClass = ...

Enfin, assurez-vous de déposer un bogue avec Apple à http://bugreporter.Apple.com . Incluez une application de test simple pour qu'il soit très clair ce que vous ' Ils se félicitent de ces rapports de bogues, même s'ils ont été soumis par le passé, car cela les aide à hiérarchiser les correctifs.

Remarque finale: cela se produit probablement parce qu'en théorie, vous auriez pu choisir d'implémenter un objet racine entièrement distinct de NSObject, et dans ce cas, il ne le ferait pas répondre à -respondsToSelector:. -[NSObject respondsToSelector:] Est en fait déclaré dans le protocole NSObject, pas dans la définition de classe. Le protocole NSObject est en fait l'endroit où la plupart de ce que vous connaissez sous le nom de NSObject vit réellement. On pourrait faire valoir que +respondsToSelector: Devrait également être là-dedans, mais pour l'instant, ce n'est pas le cas. Et puisque vous avez fourni une liste de protocoles et que la méthode n'y figure pas, elle vous donne un avertissement pour vous assurer de savoir ce que vous faites.

83
BJ Homer

Eh bien, une méthode de classe n'est qu'une méthode de l'objet de classe, vous devriez donc être en mesure de le faire

[MyClass respondsToSelector:@selector(...)]
9
newacct

Vous pouvez utiliser le instancesRespondToSelector: Suivant depuis iOS 2.0, alors où avec une instance d'une classe vous pouvez le faire;

[myInstance respondsToSelector: @selector(...)];

Avec une classe, vous pouvez utiliser

[myClass instanceRespondsToSelector: @selector(...)];
// or
[[myInstance class] instanceRespondsToSelector: @selector(...)];

Qui se comportera comme +(BOOL) respondsToSelector

5
Hugo Scott-Slade

Je pense que vous demandiez: pouvez-vous demander à une classe si elle répond à +someMethod ou pas? En d'autres termes, en pensant aux API Cocoa Touch, vous voudriez:

[ [ UIView class ] respondsToSelector: @selector( buttonWithType: ) ] -> NO
[ [ UIButton class ] respondsToSelector: @selector( buttonWithType: ) ] -> YES

Mais ce que j'ai écrit ci-dessus ne fonctionne pas comme souhaité. respondsToSelector: concerne uniquement les méthodes d'instance. (Ainsi, les deux appels renverront NON.) Dans les API Cocoa, il n'y a pas d'équivalent à respondsToSelector: pour une classe.

Vous pouvez cependant appeler class_getClassMethod. Si le résultat n'est pas NULL, la méthode de classe que vous demandez sur est présente et vous pouvez l'appeler.

1
escouten

Dans Objective C, les classes sont également des objets afin que vous puissiez envoyer les messages d'objet. En particulier, vous pouvez demander -respondsToSelector: d'une classe. Cependant, vous ne pouvez pas envoyer de méthodes de niveau classe à des objets non-classe.

0
SK9