2

Is there a way to make the compiler ignore this specific warning?

Here's what I do:

UIViewController *firstViewController = AppDelegate.instance.viewController;

//open the view of the clicked subItem
if ([firstViewController respondsToSelector:@selector(openView:inView:)]) {
    [firstViewController openView:subItem.itemText.text inView:activeScreen]; //warning on this line
}

I know one way that works is to change UIViewController to ViewController (Name of it's class). But this fix won't work in the future, so I'm just looking for a way to ignore this warning.

It won't work in the future because, I'll be doing something like this:

//.m

UIViewController *firstViewController;

//.h

if (someCondition) {
firstViewController = AppDelegate.instance.viewController;
}
else{
firstViewController = AppDelegate.instance.otherViewController;
}

if ([firstViewController respondsToSelector:@selector(openView:inView:)]) {
    [firstViewController openView:subItem.itemText.text inView:activeScreen]; //warning on this line
}
Neil
  • 2,004
  • 3
  • 23
  • 48
  • "But this fix won't work in the future" - Why not? You should be doing *exactly that.* –  Feb 01 '13 at 17:08
  • Thanks. You can just cast away the object then (see my answer). –  Feb 01 '13 at 17:16

3 Answers3

3

You should cast the object to the correct type where appropriate. Note that you can 'cast' to a protocol if you like. This gives you the safety of knowing that required methods are implemented without having to know the concrete type.

If you want to just have the compiler not complain, it's possible by calling performSelector:. But then you won't get compile-time checking.

[object performSelector:@selector(doSomething)]; 

See discussion: Using -performSelector: vs. just calling the method

If you want to pass exactly one object to your selector, it's possible by using the variant performSelector:withObject:.

If you want to pass multiple objects, you'll have to wrap them up in a container object, as described at iOS - How to implement a performSelector with multiple arguments and with afterDelay?.

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
  • And you also can't have multiple arguments. –  Feb 01 '13 at 17:18
  • yeah. with that I can't have the arguments – Neil Feb 01 '13 at 17:19
  • I think this is the best solution for my problem. Thanks. – Neil Feb 01 '13 at 17:23
  • I'd avoid using performSelector if you can define a protocol and then cast to that (and have the appropriate concrete object conform to that protocol). It's nicer to have compile-time checking. – occulus Feb 01 '13 at 17:32
1

In this case, you can just issue an explicit type conversion (cast):

UIViewController *firstViewController;
// ...

[(FirstViewController *)firstViewController openView:subItem.itemText.text inView:activeScreen];
0

Make sure to import the FirstViewController.h, so that method is known to the compiler. Tweak your code a bit:

UIViewController *vc = AppDelegate.instance.viewController;

//open the view of the clicked subItem
if ([vc respondsToSelector:@selector(openView:inView:)]) {
    FirstViewController *firstViewController = (FirstViewController *) vc;
    [firstViewController openView:subItem.itemText.text inView:activeScreen];
}

That should do the trick.

Dave
  • 7,552
  • 4
  • 22
  • 26
  • Just read your update. Don't worry about the future, on iOS you will not be dynamically linking against that code. You will not need to guard against methods that used to be there but aren't anymore, or for new methods that might exist in the future. Apple does that sort of thing because you are dynamically linking to their frameworks. YOUR iOS code can never do this (Mac code can). – Dave Feb 01 '13 at 17:19