tags:

views:

185

answers:

5

Hey guys,

I have an init method defined as:

- (id)initWithX:(float)inX AndY:(float)inY
{
    if (self = [super init])
    {
     [self setX:inX andY:inY];
    }

    return self; 
}

When I use this method like this:

MyObject* myObject = [[MyObject alloc] initWithX:0.0 AndY:0.0];

I get a warning saying: "warning: initialization from distinct Objective-C type"

But interestingly, if I change the "AndY:" to "andY:" in the method signature, the warning goes away.

Why would this be happening? Surely the naming of my method shouldn't affect its return type??


After a little more investigation, changing the method name use use the lowercase 'andY' didn't make the warning disappear. I cleaned all targets, and rebuilt and the warning didn't show. But it came back after another recompile. Odd.

+2  A: 

Did you declare it with a lowercase "and" in your .h file?

Dave DeLong
+4  A: 

This is a bit vague without the full code context, but I'll try to answer your question.

The naming of a method selector should not affect its return type. However, if the method names are mismatched (for example, it's called -initWithX:andY: in the @interface, but -initWithX:AndY: in the @implementation) you can run into strange problems. Incidentally, the Cocoa convention for multi-part selectors is to begin each fragment with a lowercase letter.

Quinn Taylor
Also, incidently, Apple's coding guidelines from upon using "and" to connect arguments as in andY:(int)intY"Don’t use “and” to link keywords that are attributes of the receiver."http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html
Toon Van Acker
An excellent point! I'd forgotten that, but it's great advice.
Quinn Taylor
This was the first thing I checked, but it's not the problem. The declaration in the interface matches the definition in the implementation perfectly.The method signature used in the interface is: - (id)initWithX:(float)x AndY:(float)y;
Jasarien
+2  A: 

I suspect, like others have mentioned, that you've named the methods differently in the class interface delcaration (the @interface block, probably in a .h file) and the method implementation (inside the @implementation block). When the Objective-C compiler encounters an unknown method, it assumes that input arguments are of type id (an object reference). So, when it encounters the method using the AndY: naming, it doesn't recognize the method (selectors are case sensitive) and assumes the inputs should be type id. Since you're passing inputs of type float, you get the warning. Obviously when the method is recognized and the compiler knows the inputs are type float, you don't get the warning.

Barry Wark
+1  A: 

I suspect that if you had named the method incorrectly you'd have got a different warning (initWithX:AndY: method not found).

What is the declaration in the header file returning? Declaring the method as

- (NSObject*)initWithX:(float)inX AndY:(float)inY;

for example, would give you this warning.

Gavin Maclean
the signature returns an id. - (id)initWithX:(float)x andY:(float)y;
Jasarien
+1  A: 

There appears to be something else at work here, and I'm not entirely sure what.

I read the cocoa guidelines and the naming methods topics, where it says not to use and to link keywords, thanks to Toon Van Acker for the link.

I removed the "andY:" exchanging it simply for "y:" and the warning has disappeared, regardless of how many cleans and rebuilds I do.

I still don't understand why this would cause the compiler to throw a warning though. Even though it goes against the naming methods guidelines, the method signatures matched in the header and implementation...

Jasarien