32

I'm trying to upgrade my app with Xcode5 but encountered a number of 'Semantic issues' in a third party library (being MagicalRecord). The quickest way to 'fix' this might be using the:

#pragma GCC diagnostic ignored "-Wundeclared-selector"

(from: How to get rid of the 'undeclared selector' warning)

compiler directive, but my gut-feeling says this is not the appropriate way to do this. A small code sample with the above error:

+ (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context {

    if ([self respondsToSelector:@selector(entityInManagedObjectContext:)]) 
    {
        NSEntityDescription *entity = [self performSelector:@selector(entityInManagedObjectContext:) withObject:context];
        return entity;
    }
    else
    {
        NSString *entityName = [self MR_entityName];
        return [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
    }
}

where the entityInManagedObjectContext: method is not defined anywhere.

Any suggestions on how to best fix these types of errors, thanks in advance?!

Community
  • 1
  • 1
iOS-Coder
  • 1,181
  • 1
  • 14
  • 28

4 Answers4

25

Yes you should.

instead of doing this:

[self.searchResults sortUsingSelector:@selector(compareByDeliveryTime:)];

you should do this:

SEL compareByDeliveryTimeSelector = sel_registerName("compareByDeliveryTime:");
[self.searchResults sortUsingSelector:compareByDeliveryTimeSelector];
newton_guima
  • 1,569
  • 2
  • 18
  • 26
  • Thanks. This also eliminated a "The app references non-public selectors In Payload" warning I got during the submission process. After declaring the selector as laid out above, I was able to submit the app without any warnings. – David L Sep 21 '13 at 04:33
  • 8
    Any idea *why* was the default build setting switched? What does calling `sel_registerName` (thus explicitly `registering a method with the Objective-C runtime`) buy you (besides the extra line)? – Blaz Sep 25 '13 at 17:10
  • 2
    It seems to me that this does not *fix* the warning, it simply hides it. Fixing it properly should involve including the file where the selector was declared, because then if that selector is renamed for some reason, the warning will reappear, which is what we should want. – Brane Feb 18 '14 at 16:10
  • I think I remember reading something about this being required when the 64bit ARM stuff came in. I can't find the doc now though. – i_am_jorf Apr 28 '14 at 21:45
  • There is some relevant stuff here: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown – i_am_jorf Apr 28 '14 at 23:14
  • In Xcode 6, this merely transfers the warning to the second line and replaces it with `PerformSelector may cause a leak because its selector is unknown` – Carlos P Dec 23 '14 at 15:01
21

You just need to declare a class or protocol that contains the selector. For example:

//  DeliveryTimeComparison.h
#import <Foundation/Foundation.h>

@protocol DeliveryTimeComparison <NSObject>

- (void)compareByDeliveryTime:(id)otherTime;

@end

And then simply #import "DeliveryTimeComparison.h" in any class where you plan to use @selector(compareByDeliveryTime:).

Or alternatively, just import the class header for any object that contains a "compareByDeliveryTime:" method.

Abhi Beckert
  • 30,929
  • 11
  • 77
  • 106
  • I agree with the above method, because turning off warnings is not my preferred way of 'fixing'. With the appropriate header file and class/protocol names I'm able to find this documented 'quick-fix' easier. So for the time being I think I'll adopt Abhi's method. – iOS-Coder Oct 23 '13 at 17:38
  • 1
    This sounds fine unless you can't really include/import the class where the selector should be (cycle dependency problems, ..) – Gyfis Mar 10 '14 at 09:15
15

Xcode 5 turned this on by default. To turn it off go to "Build Settings" for your target under "Apple LLVM 5.0 - Warnings - Objective C" -> "Undeclared Selector" set it to "NO". This should take care of it.

Jason Shehane
  • 403
  • 4
  • 6
  • 6
    this doesnt answer the question about how to fix the warning, instead prevents the warning from happening.. -1 for this! – newton_guima Sep 20 '13 at 14:54
  • 7
    Agreed. But for those of us with bigger iOS 7 issues to resolve, this allows you to hide those until you can deal with them at a later time. And you'll have no issue submitting apps with these warnings. – Jason Shehane Sep 23 '13 at 19:01
10

These selector warnings in MagicalRecord are for compatibility with mogenerator's generated Core Data classes. Besides using mogenerator and perhaps importing one of the entities there really isn't much you can do besides what was already answered.

Another option of course is to surround that code specifically with ignore blocks

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

and at the end

#pragma clang diagnostic pop
Keyd
  • 163
  • 1
  • 6