Reputation: 7717
I am working on a project where I have a class which has UIView
property. I also define a class which is a subclass of UIView
which defines a certain method. If I have the following code, I get a warning when I build:
// In this example, myView is UIView property which *may* contain a UIView or
// my subclassed-UIView which has the myMethod method
if([myView respondsToSelector:@selector(myMethod)]){
[myView myMethod]
}
The warning is "UIView may not respond to '-myMethod'". The warning obviously doesn't stop the app from being built, but I am just trying to figure out how to deal with it. Is this the correct way to do this? Is there a way to stop this warning?
Upvotes: 2
Views: 320
Reputation: 237110
This is a static typing warning, telling you that the type the variable is declared as does not respond to that selector. Since you're actually using a subclass that you've confirmed responds to the selector, you know this isn't a problem, but the compiler isn't smart enough to figure this out. There are a few ways you can fix this. In decreasing order of safety:
Cast the variable to what it actually is that does respond to the selector, either a specific class or a protocol. You'll still need to import the appropriate header or the compiler will suspect you mistyped something. Which option is best depends on your situation (e.g. whether there's one "correct" class to cast to).
[(id<SomeProtocolWiththatSelector>)myView myMethod];
[(SomeUIViewSubclass *)myView myMethod];
Cast the variable to id
to disable static typechecking. You'll still need to import a header with the declaration so the compiler knows some method exists or it will still give the "I'm not sure if this is a real method" warning.
[(id)myView myMethod];
Use performSelector:
. This will not do any checks at compile-time, so you don't need to import any headers besides Foundation, but the compiler won't catch any typos either, so any mistakes you make mean the program goes boom at runtime.
[myView performSelector:@selector(myMethod)];
Upvotes: 1
Reputation: 118751
The warning is only because the compiler doesn't know if that view is your custom subclass. Of course, at runtime it will work fine, since it will be a subclass. You have two options to fix it:
[myView performSelector:@selector(myMethod)];
(So the compiler doesn't check the method call at all)
Or, better:
[(MyViewClass *)myView myMethod];
That way the compiler acts as if the object really is your view subclass (after you performing the check of course).
For that matter, it might make sense to check for your class rather than the method:
if ([myView isKindOfClass:[MyViewClass class]]) { ...
Upvotes: 5