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]

Reply via email to