Reputation: 1448
Xcode 4 is giving me (rather unhelpful) errors about "unimplemented selector 'xxx'" when I try to use @selector(xxx) with any method not actually defined in the same source file. The error goes away (at least for the project build) if I set the LLVM compiler warning, "Multiple Definition Types for Selector" to "No". (This is the iOS default, but for my project it had been enabled.) However, even with this off, the error still shows up in the editor if "Enable live issues" is checked in the Build Settings dialog.
So now I've turned off live issues so as not to be distracted, which is a bit of a let down. My question is: Is there a way I can get rid of the error by, perhaps, specifying which definition of a selector I want to use? Or should it even matter, i.e. do all definitions of a method share the same selector in Objective-C? Is this a compiler bug, or perhaps a bogus setting that I should just leave off? (And if the latter, why is it on for the live build feature in the new editor?)
Here's the code, just to be clear:
if ([recognizer respondsToSelector:@selector(translationInView:)]) {
...
}
And here's the error:
error: unimplemented selector 'translationInView:' [-Wselector,2]
if ([recognizer respondsToSelector:@selector(translationInView:)]) {
^
If I replace 'translationInView:' with a method defined in the same source file, there's no error. I've imported the header which defines this method, and I've tried declaring the method in a category within this source file. Doesn't matter.
I'm leaving the warning off and live builds off and moving on for now, but I'd love to find a better resolution for this issue. At the very least, I'd like to learn whether Objective-C's @selector has a syntax for selecting a particular definition of a method, since I have not found any sign of this anywhere so far.
Thanks!
Upvotes: 6
Views: 1313
Reputation: 19281
Personally I consider this to be a bug in the compiler, because the error shows up even when the selector is declared in a different category, in which case the compiler should safely assume that it is not implemented in this source file. The compiler should flag this as a possible issue to be confirmed at link-time and only if there is truly no implementation once all objects/libraries are linked should it cause this warning.
Upvotes: 0
Reputation: 185661
Selectors don't have any ties to definitions. At its basic level, it's really just a unique value that identifies the name of a method. The following methods all have the exact same selector:
- (void)doSomething:(id)foo;
- (int)doSomething:(NSUInteger)i;
- (void (*)())doSomething:(char *)name;
These methods all have the exact same selector @selector(doSomething:)
.
I believe the problem is when you're referencing @selector(translationInView:)
the compiler is telling you that it's never seen any method, anywhere, that has that selector, though I can't be sure because you didn't paste your exact error. You should make sure that the header file that declares this method is actually imported into your current file. Or if you can't do that, you could always declare the method in a category on NSObject, like so:
@interface NSObject (SelectorStuff)
- (CGPoint)translationInView:(UIView *)view;
@end
That will tell the compiler that this selector exists, though it will also have the side effect of allowing you to call [foo translationInView:bar]
on any object in this file without getting a warning (of course, this will still fail at runtime).
Upvotes: 5
Reputation: 15597
If you're using the GCC front-end, you have to set this flag to get those warnings:
-Wundeclared-selector
Note that this flag isn't set by default, so that would somehow have to have been added to your build configuration in order for you to be seeing the warning now.
Upvotes: 0
Reputation: 37388
From the Objective-C Programming Language Guide:
Compiled selectors are of type SEL. All methods with the same name have the same selector.
...
For efficiency, full ASCII names are not used as method selectors in compiled code. Instead, the compiler writes each method name into a table, then pairs the name with a unique identifier that represents the method at runtime. The runtime system makes sure each identifier is unique: No two selectors are the same, and all methods with the same name have the same selector.
So as far as selectors go, the definition doesn't matter... only the name of the method.
Upvotes: 1