3

The following code is perfectly safe, yet Xcode 4 gives me an error for it:

    if ([self respondsToSelector: @selector(foo)])
        [self foo];

I am aware that I can get around it with a dummy protocol, but I use this pattern pretty often, and it feels like that amount of work should not be necessary. Is there any way to set a setting somewhere, preferably once, so that this "error" does not bug me again?

William Jockusch
  • 26,513
  • 49
  • 182
  • 323

2 Answers2

4
if ([self respondsToSelector: @selector(foo)])
    [self foo];

That expression is only "perfectly safe" if there are no arguments and no return value. If any type information is required, @selector(foo) is insufficient.

Even then, I suspect that there are architectures whose ABI are such that the no-arg-no-return case would actually require that type knowledge be available to the compiler to be able to generate code that is absolutely guaranteed correct.

That is to say, your example of fooWithInteger: and/or fooWithX:y:z: could not possibly be compiled correctly without the full type information available due to the vagaries of the C language and the architecture specific ABI.

As well, to allow the compiler to compile that without warning would require the compiler to collude a runtime expression -- respondsToSelector: must be dynamically dispatched -- with a compile time expression. Compilers hate that.

bbum
  • 162,346
  • 23
  • 271
  • 359
0

To silence the compiler when following that kind of pattern, I use -performSelector:

if ([self respondsToSelector:@selector(foo)]) {
    [self performSelector:@selector(foo)];
}

I don't know of any other way.

Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
  • Ugh, could be problematic if what I really want to do is [self fooWithInteger: 2]; . . . or, much worse, [self fooWithX: 1 y: 2 z: 3]; – William Jockusch Aug 03 '11 at 02:22
  • @William: Indeed. I've avoided similar method signatures for that very reason. I find situations where I need to conditionally send messages based on responsiveness rare though, so it hasn't bugged me enough to explore other options. Just my two cents. – Matt Wilding Aug 03 '11 at 02:24
  • @WilliamJockusch: you can use NSInvocation to do that. – Andrey Zverev Nov 21 '11 at 09:43