Parijat Kalia
Parijat Kalia

Reputation: 5095

Multiple parts of methods in Objective C

I am learning Objective C and noticed this funky quirk while reading up on methods.

Like Java and C++, Obj.C can take in multiple parameters, which is fine, however it states that objective C methods can have multiple names which does not seem to register to well with me.

For instance:

-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

In the above example, there are two parameters, bombLocation (return type CGPoint) and damaged (return type BOOL) and alongside the method name seems to be split as shipsatpoint:withDamage

I don't understand what's up with this... What does it signify when it states that a method can have multiple names? Is this applicable only for methods that require multiple parameters? Alternately, say I want to name my method with a single name but provide it with multiple parameters, is that possible or I must provide it with multiple names each of which correspond to a parameter? If yes, then why?

Thanks for jumping in with my confusion!!! :)

Upvotes: 5

Views: 605

Answers (5)

Rob Napier
Rob Napier

Reputation: 299623

Objective-C uses a system of message passing based on selectors. This is not quite the same thing as method calling. When you see code like this:

[world shipsAtPoint:point withDamage:YES];

That is converted into the following C call (in the most common case):

objc_msgSend(world, @selector(shipsAtPoint:withDamage:), point, YES);

The @selector() construct returns a unique identifier. The exact format of that identifier is an internal implementation detail.

objc_msgSend includes quite a lot of logic in it's few dozen bytes of assembler. But in simplest case, it looks up the class for world, walks through a table of selectors until it finds the one that matches shipsAtPoint:withDamage: and then grabs the function pointer at that slot. It then jumps to that function pointer, leaving the rest of the parameters alone (in registers or on the stack as appropriate for the processor). The function at that location is your method, and it knows the order and types of its parameters based on your declaration.

What's important in all this for you is that the selector is shipsAtPoint:withDamage:. This is generally the one-and-only name of the method. There are not "multiple names" as you suggest. (Usually.... the Objective-C runtime is very powerful and it's possible to point multiple selectors to the same implementation.)

As Joe points out, a selector can be in the form foo::. This would represent a method that took two parameters and would be called like [world foo:point :YES]. You should never do this. It's incredibly confusing to read. But it's legal.

Upvotes: 3

Matt S.
Matt S.

Reputation: 13773

The reason is to make it easier to understand.

With your example, the method would be something like this in C++:

 int shipsAtPointWithDamage (CGPoint bomb, BOOL damage)  //I don't really know C++ 

OK, so the first parameter is the ship's point, and the damage is the second. It's easy enough to figure out, but that's the thing, you have to FIGURE it out, you have to look at the method to try and figure out what each thing is.

In Objective-C you have

-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

Each parameter is clearly defined, the first is the ship's point, the second is damage. It reads like a sentence, whereas with C++ (and almost every other language) it doesn't.

If you want a method to have multiple parameters in Obj-C you have to write it this way:

-(returnType)paraOne:(type*)name paraTwo:(type*)name

It's something that just takes getting used to, every language is different. Once you get used to the way Objective-C does things, you'll think it's absolutely fantastic.

EDIT: and as filipe pointed out, because the method as multiple parameters it doesn't mean it has multiple names, in the example I gave above, the method name would be paraOne:paraTwo, NOT paraOne:

Upvotes: 6

Alex Wayne
Alex Wayne

Reputation: 187262

I think you are confused. A method cannot have multiple names, but the argument may be named differently in the header then they are in the implementation.

The name of that method is shipsAtPoint:withDamage:. This is also known as a selector.

This method returns an instance of NSArray, and accepts a CGPoint as the first argument, and a BOOL as the second argument.

The names of the arguments may differ, however. This is totally valid:

// .h file
-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

// .m file
-(NSArray *)shipsAtPoint:(CGPoint)loc withDamage:(BOOL)dmg {
  // ...
}

Lastly, ObjC is mainly some nice syntax sugar. You should know that any method invocation really just boils down to some C that looks more or less like this:

objc_msgSend(receiverObj, @selector(shipsAtPoint:withDamage:), point, damage);

So at the end of the day, you have a receiver, a selector, and your arguments. But the ObjC syntax is much nicer than that.

Upvotes: 2

Joe
Joe

Reputation: 57179

It is possible provide a method without labeled parameters but it is obviously discouraged.

-(void)badmethod:(id)obj1:(id)obj2:(id)obj3
{

}

//...
//Usage
[self badmethod:nil :nil :nil];

SEL sel = @selector(badmethod:::);

Upvotes: 0

Jesse Naugher
Jesse Naugher

Reputation: 9820

Here is the best explanation i've ever seen. It includes comparisons with C++/C as well as lots of other good info.

Upvotes: 2

Related Questions