0

In response to a comment made on this question: Is it possible to suppress Xcode 4 static analyzer warnings?, here is a false positive (or at least I believe so).

The code below gives the following message:

Although the value stored to 'action' is used in the enclosing expression, the value is never actually read from 'action'

NSArray *actions = [button actionsForTarget:target forControlEvent:controlEvent];
if (actions)
{
    NSEnumerator *actionEnumerator = [actions objectEnumerator];
    NSString *action;
    while ((action = (NSString *)[actionEnumerator nextObject])) 
    {
        [button removeTarget:target action:@selector(action) forControlEvents:controlEvent];
    }
}
Community
  • 1
  • 1
jonoogle
  • 11
  • 1

3 Answers3

3

That's because when you do @selector(action), it's a reference to a selector called "action". In other words, the argument to @selector is parsed as a literal, not a variable.

Since the action variable is referring to an NSString naming a selector, what you want is probably:

[button removeTarget:target action:NSSelectorFromString(action) forControlEvents:controlEvent];

Actually, you don't even need to iterate through the actions. A better way to do this is this one-liner:

[button removeTarget:target action:NULL forControlEvents:controlEvent];
Daniel Dickison
  • 21,832
  • 13
  • 69
  • 89
  • you're right and thanks for the heads up. Other than being asleep I should read the manual more carefully. – jonoogle Jun 16 '11 at 21:09
2

This is not a false positive, it is a real (your) bug.

@selector(action) describes a method with the name action. It does not describe a method with the name that is stored in the variable action!

The static analyzer just saved your... ;-)

Eiko
  • 25,601
  • 15
  • 56
  • 71
  • I have to admit that it took me quite a while to figure out as well. Lesson is to trust the tools in 99%. :-) – Eiko Jun 16 '11 at 21:22
  • Exactly! I was once the tool maker (and made the bugs in the tools ;). The mistake was stupid (on my part) but one of those that you look at it 100 times (and I did study the line of code many times before posting) and it looks right but it's wrong :( I rechecked my code and out of 279 @selectors, that was the only wrong one. – jonoogle Jun 17 '11 at 09:53
1

The static analyzer is right, you don't use/read action it! @selector() doesn't take a NSString, so it always returns the selector for a method called action. Plus: @selector() is a compile time function, the compiler will replace it with a static value. Pretty much like sizeof() does with the size of data structures.

You should use NSSelectorFromString() to get a selector from an NSString.

JustSid
  • 25,168
  • 7
  • 79
  • 97