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!
In Objective-C, selector has two meanings. It can be used to refer simply to the name of a method when it's used in a source-code message to an object. It also, though, refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL .
A selector is an identifier which represents the name of a method. It is not related to any specific class or method, and can be used to describe a method of any class, whether it is a class or instance method. Simply, a selector is like a key in a dictionary.
In Swift, you create a selector for an Objective-C method by placing the name of the method within the #selector expression: #selector(MyViewController. tappedButton(_:)) .
A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn't do anything. It simply identifies a method.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With