Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C isEmpty helper suddenly stopping build

I've got this beautiful & convenient helper inline function that i have in a project (originally has it's roots in here & here):

static inline BOOL isEmpty(id thing) {
    return !thing
    || [thing isKindOfClass:[NSNull class]]
    || ([thing respondsToSelector:@selector(length)] && [((id)thing) length] == 0)
    || ([thing respondsToSelector:@selector(count)] && [((id)thing) count] == 0);
}

static inline BOOL isNotEmpty(id thing) {
    return !isEmpty(thing);
}

and all works well.

it's useful for checking NSString, NSData, NSArray, NSDictionary, NSSet, and others... My issue now is that I brought it in to another project(a static framework/library that i'll be using) and have the following issue that is stopping my project from building:

Multiple methods named 'count' found with mismatched result, parameter type or attributes

I'm using the same(latest) version of xCode with both so not sure what the difference could be that would stop this on one side and not the other... The project settings are obviously different in either project (as mentioned, one is a framework and one is a regular project) but would that do it?

thanks in advance!


POST-SOLUTION-EDIT for future visits:

hold command and click on the method or property to get a drop down of all the instances that the compiler is seeing... you likely have conflicting return types.

like image 910
MrTristan Avatar asked Oct 03 '22 02:10

MrTristan


1 Answers

It sounds like the problem is that some class(es) in the framework/library declares a -count method that returns something different than -[NSArray count] (etc.).

Even when you're sending a message to an object of unknown (id) type, the compiler needs to know some information about the method that will be called, including the return type. In short, this is because the message send path is different depending on the return type of the method that will be called. In cases like your code, the compiler will look for any method declared in the project with a name matching the message you're sending, and assume that's the method that will be called for the purposes of figuring out return type, etc. In this case, it's finding two different methods with the same name, but which have differing return types, and therefore doesn't know the exact semantics required for sending the count message.

The quick and dirty solution is to change the cast in your isEmpty() function to [(NSArray *)thing count]. This should work fine as long as you never call isEmpty() with instances of whatever class it is that has a different -count method.

like image 129
Andrew Madsen Avatar answered Oct 13 '22 11:10

Andrew Madsen