Class method equivalent of -respondsToSelector:
Is there a class method equivalent to -respondsToSelector:
?
Something like +respondsToSelector:
?
The reason I am asking is because by implementing -respondsToSelector:
on a class level, I get a compiler warning: "found '-respondsToSelector:' instead of '+respondsToSelector:' in protocol(s)".
The code looks like this:
Class <SomeProtocol> someClass = [someInstance class];
if ([someClass respondsToSelector:@selector(someSelector:)]) {
someVar = [someClass someSelector:someData];
}
Solution 1:
Update after seeing your edit:
A class object responds to respondsToSelector:
just fine, as you're probably aware. In a test application, I can do both of the following without any compiler warnings:
NSLog(@"Responds to selector? %i", [MyObject respondsToSelector:@selector(respondsToSelector:)]);
NSLog(@"Responds to selector? %i", [[MyObject class] respondsToSelector:@selector(respondsToSelector:)]);
However, you've declared a protocol on your variable, so it assumes that the class object you're pointing to implements those methods. The simplest solution would be to cast someClass
as an id
for the purpose of calling respondsToSelector:
. A somewhat cleaner solution would be to declare your own @protocol
which declares +respondsToSelector:(SEL)selector
, and then declare someClass
as follows:
Class<SomeProtocol, ClassRespondingToSelector> someClass = ...
Finally, be sure to file a bug with Apple at http://bugreporter.apple.com. Include a simple test application so that it's very clear what you're doing. They welcome such bug reports, even if they've been submitted in the past, as it helps them prioritize the fixes.
Final note: this is probably happening because in theory, you could have chosen to implement a root object entirely separate from NSObject, and in that case, it wouldn't respond to -respondsToSelector:
. -[NSObject respondsToSelector:]
is actually declared in the NSObject
protocol, not the class definition. The NSObject
protocol is actually where most of what you know as NSObject
actually lives. One could argue that +respondsToSelector:
should also be in there, but as of now, it's not. And since you've provided a protocol list, and the method isn't in there, it gives you a warning to make sure you know what you're doing.
Solution 2:
Well a class method is just a method of the class object, so you should be able to just do this
[MyClass respondsToSelector:@selector(...)]
Solution 3:
You can use the following instancesRespondToSelector:
since iOS 2.0, so where with an instance of a class you can do;
[myInstance respondsToSelector: @selector(...)];
With a class you can use
[myClass instanceRespondsToSelector: @selector(...)];
// or
[[myInstance class] instanceRespondsToSelector: @selector(...)];
Which will behave like +(BOOL) respondsToSelector
Solution 4:
What I think you were asking is: Can you ask a class if it responds to +someMethod
or not? In other words, thinking of the Cocoa Touch APIs, you would want:
[ [ UIView class ] respondsToSelector: @selector( buttonWithType: ) ] -> NO
[ [ UIButton class ] respondsToSelector: @selector( buttonWithType: ) ] -> YES
But what I wrote above doesn't work as desired. respondsToSelector:
is only about instance methods. (Thus both calls will return NO.) Within the Cocoa APIs there is no equivalent to respondsToSelector:
for a class.
You can, however, call class_getClassMethod
. If the result is non-NULL, the class method you are asking about is present and you can call it.