LearnThe Beginner’s Guide to Objective-C: Methods

   
Avatar

Ben Jakuben
writes on October 31, 2013

Writing a killer iPhone or iPad app doesn’t require you to be a master of Objective-C, but the more comfortable you are with the language, the more you’ll enjoy it! Writing your own app may seem insurmountable at first, but if you start at the beginning with learning how and why a programming language works, then you can use those building blocks to create complex and amazing things, one step at a time.

Getting comfortable with the Objective-C programming language requires getting your hands dirty with some code. But you don’t want to dive right in without any prior knowledge, which is why we are here at Treehouse! This is the second in a series of posts that talk about the basics of Objective-C and how you can use it to write iOS apps. In the previous post we talked about the language itself and understanding variables, and in this post we will focus on an important basic concept known as methods. Objective-C on iPhone Screen

Code Comments

But first, let’s start with a programming language feature that can at times be the single most useful feature to a programmer – Comments. A good comment can be worth the effort of a thousand programmers (though the reverse is also true…). It can be incredibly helpful to document the code that we write within the code itself. We basically leave notes to ourselves or other developers to explain what the code is doing.

We do this in Objective-C and other programming languages using comments. Comments in Objective-C code are lines of code that don’t have any effect on how the program runs. They are purely informational, meant to help us understand how the code works or is organized.

Single-Line Comments

Single line comments begin with two forward slashes: //. Everything on the line after the forward slashes makes up the comment and is completely ignored by the program.

// This is a single-line comment
NSString *badWord = @"Android"; // Only this part is a comment

Multi-Line Comments

Sometimes we want longer comments that span more than one line. In that case we use an opening marker to mark the start of the comment: /*, and a closing marker to mark the end of the comment: */.

/* This is a multi-line comment. Though only the opening
 * and closing markers are required, we often add an 
 * asterisk at the beginning of each line to make it
 * more readable, and end the comment with the ending
 * marker on a new line.
 */

Methods, Messages, and Functions

The terms “method”, “messages”, and “function” all kind of refer to the same thing in Objective-C. You may hear them used interchangeably, though there are differences. I will stick with the terminology “calling a method” in this post. A method (or message or function) is a section of code that we can call from elsewhere in our code, and the method will perform some action or return some kind of result that we can use. Methods are used to organize our code into reusable (and understandable) chunks that save us a lot of time and energy.

Let’s illustrate this concept with an example. The NSString class has a method called length that gives us the number of characters in the string. The definition and code for this example might look like the following:

01  - (int)length {
02    int numberOfCharacters = 0;
03    // ... code to calculate the number of characters ...
04    return numberOfCharacters;
05  }

Line 1 declares the method named length. The very first character is a dash: “-“. In Objective-C, method definitions begin with either a dash (-) or a plus (+). We’ll talk about this in more detail when we cover classes and objects, but the dash means that this is an instance method that can only be accessed by an instance of the class where the method is defined. A plus sign indicates that the method is a class method that can be accessed anytime by simply referencing the class.

In terms of our example, this means that we need to call the length method on an actual string, an instance of NSString. This makes sense because we would only ever want to know the lengths of real, live strings. A class method (with the plus sign) would be used in other circumstances, like when we first want to create an NSString instance variable, for example.

After the dash (or plus), we get a pair of parenthesis with an important word inside. This word is the return type of the method. In other words, it specifies what type of data will be returned by this method. In this example, we are going to return a simple int because the length will simply be a number.

Some methods will do some work but won’t actually return any data. In these instances, we use a special keyword, “void,” to indicate that no data will be returned: (void). If we wanted to return a string instead, we would put “NSString *” in the parenthesis: (NSString *). (Remember from part 1 that the asterisk indicates a pointer, so we actually return pointers to the places in memory where strings are stored.)

Next we get the actual name of the method. In this simple example the name is simply “length”. Then we have a pair of curly braces that surround the lines of code that make up the method. If a method returns data (i.e. it’s return type is not (void)), then the last line of the method must contain the return keyword followed by the data to be returned. The return keyword ends execution of the method, so any code written after that would not be executed.

Calling a Method (a.k.a sending a Message)

"I'm sending a message!" "You mean calling a method?" "Yes. Well, technically, no."

Okay, so we have defined a simple method. Now what? How do we use it? What good does that do for us?

01  NSString *emailAddress = @"ben@objectivecfun.com"
02  int stringLength = [name length];
03  // stringLength will equal 21!

The example above shows how a method is used. Here we are calling the length message on the emailAddress variable, or more accurately, sending the length message to the emailAddress object.

A Quick Explanation of “Method” vs. “Message”

Objective-C is based on a message passing model that is kind like calling methods plus some other goodies. It’s essentially the same as calling a method like in many other programming languages, which is why they are often used interchangeably. Message passing is different in that any message can be sent to any object. It’s up to the object to handle the message or not. If it doesn’t handle the message, then nothing bad will happen; it will just return nil to the sender, or caller. This is different than the method model because, If a method is called on an object that doesn’t define the method, we end up with compile-time or run-time errors that stop us dead in our tracks.

01  NSString *testString = [emailAddress addSparkles]; 
02  // testString will equal "nil" because, believe it or not,
03  // "addSparkles" is not a valid NSString method.

Okay, back to our discussion…

Remember that those square brackets are used to differentiate Objective-C constructs from plain old C code. The square brackets around name length indicate the method call. The method calculates the length to be 21 and it is returned to where it was called from. We do something with this return value by storing it in a new int variable named stringLength. It’s as if 21 takes the place of [name length]:

01  // We can basically replace the method call with 
02  // the value it returns
03  int stringLength = 21;

Method Parameters

Methods will often include extra pieces known as parameters, which are sometimes referred to as arguments. Let’s work with a new example since length doesn’t require any parameters. The method below simply adds two int numbers:

01  - (int)addX:(int)x toY:(int)y {
02      int sum = x + y;
03      return sum;
04  }

Let’s be honest; that looks a little crazy. If you are learning Objective-C after using another language (like JavaScript, for example), this can be a little hard to read and understand. Let’s break it down piece by piece. The first part of the definition, or method signature, is similar to what we saw for length:

- (int)addX

The dash means that this is an instance method,  (int) means that it will return an int value, and the name starts with “addX”.

Parameters are specified with a colon after the name, a data type, and their own name.

 :(int)x

This means that the first parameter of this method is an int variable named x.

Additional parameters are specified in the same way, but what is a little weird is that we also add a new piece to the name of the method. So we type a space and add the following:

toY:(int)y

The first part, “toY”, is actually part of the message name. The full message name is now “addX:toY:”. Reading it without the colons explains exactly what this method does, and the colons indicate where the parameters are set. The second parameter is very similar to the first; it’s an int variable named y.

To call this method, we simply plug in variables or values for the parameters. In the length example above, the length method was defined in the NSString class, which is why we called it on a string variable. (Or we could say that we sent the length message to a string variable.) In this example, let’s pretend that the addX:toY: method is defined in a GameScore class from a game, and that we have a variable named “score” that has GameScore as its data type:

01  int points = 100;
02  int newScore = [score addX:24 toY:points];
03  // newScore now equals 124

Notice that we can use a literal value (24) or a variable that holds a value (points) for either parameter. Also notice that the names of the parameters doesn’t matter in terms of calling the method. The names are used in the definition and are used in the code that makes up the method, but they have nothing to do with the code we write when we call the method.

What is the function of a “function”?

I mentioned “functions” at the beginning of this section, because like methods, they are reusable chunks of code that we call from other places. A very common example is the NSLog() function that writes data to the operating system log:

NSLog(@"This is some string data being written to the log.");

Functions are the original “method” constructs from regular C. Their syntax is slightly different, though. In the NSLog example above, “NSLog” is the name of the function, and then its parameters are specified inside parentheses. Functions always end with parentheses, even if there is nothing in them. In this example we are passing one string parameter. The signature for this method would look something like this:

01  void NSLog(NSString *text) {
02      // Logging code
03  }

Notice that functions can be called from anywhere without any reference to the class where they are defined. Our previous examples were called on variables: emailAddress and score. Those variables framed the context in which the method was supposed to act. Functions can be called from anywhere and simply act on the data passed into them.

As a geeky bit of trivia, any Objective-C method can be rewritten in C syntax as a function. Remember again from part 1 that Objective-C maintains all the syntax from C and just adds object-oriented features as a thin layer on top of the world of C code.

Major Benefit of Using Methods

Imagine that we have five different NSString variables that we need to know the lengths of. If we didn’t have a length method to use, we’d have to write the code to calculate the length five different times. But by creating a reusable method, now we only need one line of code each time we want to determine the length of a String value. Programming is all about efficiency, so use methods whenever possible to organize your code and save yourself work.

A side benefit that comes out of this is that our code becomes much more readable when we use methods effectively. With intuitive names and clear actions, using methods reduces many lines of spaghetti code that are hard to read through and understand into simple and elegant code that we can understand quickly. We spend a lot of our time reading code as programmers, whether we are troubleshooting our old code, trying to remember what we wrote a long time ago, or trying to understand or fix somebody else’s code.

For example, there is a lot of magic that happens behind the scenes of these three lines of code, but I bet you can figure out what they do:

01  NSURL *url = [NSURL URLWithString:@"http://teamtreehouse.com"];
02  NSString *htmlData = [NSString stringWithContentsOfURL:url];
03  NSLog(htmlData);

More to Come!

We’re starting to really understand how Objective-C is organized, but we still have a lot of important programming concepts to cover, like what objects and classes are and why they are used. Once again, you can practice all of the stuff we talked about in this post in any of the iOS projects in the Treehouse Library, which all include interactive Code Challenges that allow you to write some Objective-C code in the browser. Happy coding!

GET STARTED NOW

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Get Started

16 Responses to “The Beginner’s Guide to Objective-C: Methods”

  1. Everything is very open with a really clear clarification of
    the issues. It was really informative. Your website is very helpful.
    Many thanks for sharing!

  2. Hey!

    A pal of mine new to Obj-C just asked my where “name” came from in the email length example. I think you might want to fix that. 🙂

    Great tutorial 😀

  3. Couple questions:

    1) Because the parameters after the first one have names, like “toY”, do you have to call the method with the parameters in the same order? For example, let’s say we add another parameter onto addX called “toZ”, which adds that int value as well, could you call it both of these ways:

    [score addX:24 toY:points toZ:50]
    [score addX:24 toZ:50 toY:points]

    2) Does the first parameter have to be there without a specific name? In other words, is the first parameter of a method always without a name? Or could you have a method that could be called like this:

    [score addTogether x:1 y:2 z:3]

    Thanks Ben!

    Josh

  4. To keep the flow in learners’ minds I’d also recommend updating this snippet:

    01 NSString *testString = [emailAddress addSparkles];
    02 // testString will equal “nil” because, believe it or not,
    03 // “addSparkles” is not a valid NSString method.

    By adding the emailAddress declaration again (and remove “believe it or not”), like:

    01 NSString *emailAddress = @”ben@objectivecfun.com”
    02 NSString *testString = [emailAddress addSparkles];
    03 // testString will equal “nil” because “addSparkles” is not a valid NSString method.

  5. Hey Ben,

    I believe you have a typo. This code snippet:

    01 NSString *emailAddress = @”ben@objectivecfun.com”
    02 int stringLength = [name length];
    03 // stringLength will equal 21!

    Should be:

    01 NSString *emailAddress = @”ben@objectivecfun.com”
    02 int stringLength = [emailAddress length];
    03 // stringLength will equal 21!

    Change “name” to “emailAddress”.

    Thanks!

    Josh

  6. Yes Ben and Ben,

    You are right, ’emailaddress’ should be used in the example nstead of ‘name’. As it stands now it’s a bit confusing. And I currently find that crazy method declaration and calling syntax of objective C confusing enough :).

  7. Should `[name length]` be `[emailAddress length]`?

  8. Great job with the explanations Ben.

    As someone who wrote a tutorial like this before, I can appreciate that knowing how to do it doesn’t mean that it’s easy to translate it into layman’s terms.

    It’s an awesome write-up!

  9. It is really a nice and helpful piece of details. Now i’m contented which you discussed this beneficial facts about. Be sure to continue to be all of us informed like that. Thank you for sharing.

  10. In your example:
    NSString *testString = [emailAddress addSparkles];

    If addSparkles is not implemented, this will not assign nil to testString. It will assign nil to testString if emailAddress is nil.

    What will really happen in that line of code is one of two things:
    If your code declared emailAddress as an id, you will able to compile the app, but when the unimplemented message will be sent to the object, the app will crash during runtime with the appropriate exception notifying you that the object didn’t implement that message.

    If you gave information to the compiler about emailAddress (for example, if you declared it as NSString) you will not be able to even compile and run your code. The compiler will complain that you are calling an unimplemented method/message.

    • Ben Jakuben on November 7, 2013 at 2:53 pm said:

      Argh – thanks for the comment! I am sorry about that and will set aside some time to write up a correct explanation and update this post. I even explain this in one of my videos but just didn’t think it through (or try out the code) when I wrote up that paragraph.

  11. You are wrong and misleading your readers.

    If you send a message to nil, nothing will happen. If you are sending a message to an object that doesn’t implement it, a runtime exception is raised.

Leave a Reply

You must be logged in to post a comment.

man working on his laptop

Are you ready to start learning?

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Start a Free Trial
woman working on her laptop