How to read (and write!) method declarations in Objective-C

Does the following code make any sense to you?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

If you’re not very familiar with Objective-C, you may be wondering…

“What am I looking at? What does that minus sign mean? Why are those parentheses there? How about the asterisks? Where’s the return type? What do the colons mean? And what’s with those spaces?”

Let’s start by answering the first question: “What am I looking at?” You’re looking at a method declaration in Objective-C. Pretty soon, you’ll be able to read and understand all of it. But let’s look at a simpler example:

- (void)driveCar;

This Objective-C method declaration is equivalent to this C function declaration:

void DriveCar();

You’ll notice that Objective-C doesn’t have parentheses at the end of the method – in fact, it has them near the beginning! You can think of this as a type-cast in C. You’ll also notice that we start method names with a lowercase letter in Objective-C:

- (void)driveCar;

The minus sign (-) indicates that it’s an instance method, which means it can be called on an instance of the class – as opposed to a class method that’s called on the class itself. And the name of the method is just driveCar.

Now, what if we’re particular about what car we want to be driven? How do we send that car? In C:

void DriveCar(Car car);

And in Objective-C:

- (void)driveCar:(Car *)car;

This looks a bit different – now we have a colon (:), which is just a separator that tells us a parameter is coming… And after that, we see parentheses – which you can think of as a type cast. Inside of them, we can see that we’re declaring a Car pointer called car as a parameter.

But what if we want to pass along the car and the person who should drive it?

Our C might look like this:

void DriveCar(Car car, Person person);

And the Objective-C:

- (void)driveCar:(Car *)car withPerson:(Person *)person;

Whoa…hold on a second. What’s all this? Is that a space in the method name? And another colon? More parentheses and asterisks and…aaahhh…

Relax. You’ve seen all of this before, up to the space after car. And yeah, that space – and what follows – is a little weird no matter what language you’re coming from. That space just separates the car parameter from the rest of our method name. And then we see withPerson, the second half of our method name, followed by a Person parameter.

So in Objective-C we’re being pretty verbose and declaring what each parameter should be – right in the method name. We don’t have that in C, though we could approximate it with something like this:

void DriveCarWithPerson(Car car, Person person);

I don’t write a lot of straight C, so I could be wrong… but I don’t think that’s the way C is usually written. But Objective-C, on the other hand, is often written like that. Or, rather, like this:

- (void)driveCar:(Car *)car withPerson:(Person *)person;

The fact that each parameter has a bit of the method name preceding it makes Objective-C much more verbose than lots of other languages. I think that’s a good thing, because it gives us a clear indication of what needs to be passed into the method when we call it, and it makes it more readable. So this method is called driveCar:withPerson: and it takes two parameters: a Car called car and a Person called person. Easy enough, right?

Now, back to what we started with…

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

Remember what the minus sign means?

-

That tells us it’s an instance method. (The only other option in Objective-C is a class method, which is indicated by a plus (+) sign instead.)

Moving on…

(UITableViewCell *)

Remember that the return type of the method is in parentheses just after the +/-. So here, we know a UITableViewCell will be returned when we call this method.

Here’s where it gets a bit trickier – but we’ve seen this before in the driveCar:withPerson: method.

tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

So this chunk is our method name and its parameters. The method is called tableView:cellForRowAtIndexPath: – all the words immediately preceding the colons. And the method takes two parameters: a pointer to a UITableView and a pointer to a NSIndexPath. And again, the colons are just separators to indicate that a parameter is coming.

So there you go – now you can read an Objective-C method declaration that takes multiple parameters and returns a value, wacky syntax and all. And if you can read it, you can write it. :)

Oh, and if you forget any of this, you can refresh your memory just by reading the docs (they tell you everything)…

Screen shot of the Apple documentation for tableView:cellForRowAtIndexPath:

Happy learning!

This is Part 1 in a three-part series on Methods in Objective-C. If you want to learn more, read the next two:

  1. How to read (and write!) method declarations in Objective-C
  2. How to implement methods in Objective-C
  3. How to send messages (aka call methods) in Objective-C

Want to learn Swift, too? Drop your name & email in the boxes below to get the 5-Part Guide to Getting Started with Swift.