Rob
Rob

Reputation: 7717

If object respondsTo still throws warning

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

Answers (3)

Chuck
Chuck

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:

  1. 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];
    
  2. 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];
    
  3. 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

jtbandes
jtbandes

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

John Franklin
John Franklin

Reputation: 4912

You can use:

[myView performSelector:@selector(myMethod)];

Upvotes: 1

Related Questions