On Apr 29, 2014, at 8:18 AM, Arved von Brasch <[email protected]> wrote:
> Hi List,
>
> I have a warning that I’m trying to understand. Hopefully someone here can
> shed some light on it.
>
> I have two relevant classes. My window controller:
>
> @interface ISWindowController : NSWindowController <NSToolbarDelegate>
> …
> - (IBAction)clear: (id)sender;
> ...
> @end
>
> This method is implemented and works as expected if called directly. (It
> clears the search field in the toolbar.)
>
> In the second class, an NSArrayController subclass, I have the following
> method override:
>
> - (id)newObject {
> NSManagedObject *newObject = [super newObject];
> ...
> // Clear the Search Field via the Window Controller (Responder Chain)
> [NSApp sendAction: @selector(clear:) to: nil from: table];
> …
> }
>
> sendAction:to:from: seems to be the preferred way to invoke the responder
> chain to implement the clear: method in the Window controller. However, it
> generates the following warning:
>
> “Creating selector for nonexistent method ‘clear:’
>
> I can’t figure out how to get rid of this warning. The window controller’s
> header file is imported into the second class. Removing the import causes a
> second warning to be generated on the same line, which is what I expected
> (Undeclared selector). I’ve also tried using other ways of invoking the
> responder chain, like tryToPerform:with: on the table the Array Controller is
> managing. It seems to be any attempt to use @selector() that is causing the
> warning.
>
> I know how to turn off this warning, what I’d like to understand is why it’s
> coming out at all. I thought I was doing everything right here.
I've been having the same issue, so I filed a Radar report on it a while back
(rdar://16600230). The first case that was causing it was:
NSArray *array = ...;
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)]; //
warns about nonexistent selector "compare:"
This one can be worked around by using -sortedArrayUsingComparator: instead.
What can't be as easily worked around are things like this:
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { // or -respondsToSelector:,
+resolveInstanceMethod:, etc.
SEL action = menuItem.action;
// insert any framework-defined method here; we'll use
-performTextFinderAction: as an example
if (sel_isEqual(action, @selector(performTextFinderAction:))) { // warns
about nonexistent selector "performTextFinderAction:"
// do something
}
return [super validateMenuItem:menuItem];
}
As far as I can tell, the only way to make that work without warning is to use
NSSelectorFromString, which of course undermines the purpose of having
-Wselector turned on in the first place, since any typo in the selector string
will remain unnoticed until it causes things to fail at runtime.
Unfortunately, my Radar report was closed with the status "Behaves Correctly."
This was the rationale:
"Engineering has determined that this issue behaves as intended based on the
following:
This warning is as expected. Intention of this warning is to warn about
unimplemented methods in current TU when method is used in a @selector
expression. Note that in user test case " -compare:" has been declared but not
implemented.
But, why do we get this warning only if a random @implementation is added to
the TU (as user discovered)?
This warning is issued only when the selector meta-data table is generated
which requires at least one implementation. This warning comes from gcc's
legacy and seems to enforce coding style that the @implementation in the TU
must implement the method used in the @selector expression.
We are now closing this bug report.
If you have questions regarding the resolution of this issue, please update
your bug report with that information.
Please be sure to regularly check new Apple releases for any updates that might
affect this issue."
So it seems that even if the method is defined in a header, you need it to be
in the @implementation block of a class for which you have the code in order to
use @selector without setting off -Wselector. This means that @selector cannot
be used for methods in framework classes. You will need to either use
NSSelectorFromString, find a way to use a blocks-based approach (if it's
possible), or just turn off -Wselector.
Charles
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]