In this post we’re going to walk through our first Objective-C Program and start to learn the Objective-C language itself by taking a look at each of the lines of source code in the application we created in our post on Creating Your First Objective-C Application.
As a refresher, here is the code in the main.m
source file as we left it:
//
// main.m
// HelloiOSDevelopmentTutorials
//
// Created by Andy Bargh on 30/03/2013.
// Copyright (c) 2013 Andy Bargh. All rights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
Syntax Highlighting
One of the first things that you will notice when you look at the contents of the main.m
file in Xcode is how multi-colored it is. This is Xcode doing something called syntax highlighting.
Syntax highlighting is where different colors are used to indicate reserved words (words that have special significance within the Objective-C Programming Language and therefore shouldn’t be used for any other purpose within your programs) and other types of values.
Syntax highlighting can be extremely useful when editing your code as it allows you to quickly identify whether you’ve made a mistake. If you type in a line or source code and the reserved words and values in that line or source code don’t go the color your excepting it’s immediate notification something is wrong.
Indentation, Whitespace and Capitalization
Now in addition to the syntax highlighting the other thing you will probably notice is how the lines of our main.m
file do not all start right up against the left-hand side of the Xcode editor window. This is something called indentation.
Indentation is an approach to laying out your source code to help convey the programs structure to readers of your source code.
Indentation along with the blank lines are all examples of using whitespace – horizontal or vertical space added to your source code to help increase its clarity for a reader.
Whitespace does not affect the logical meaning of your source code, so things like indentation and blank lines are not a requirement, but laying out your source code in a clear and readable fashion is seen as an essential part of being a good Objective-C programmer so I would advise you to add it when writing your own source code.
As you might expect, Xcode will help you with adding white space to your source code.
First up are two key combinations to indent and outdent your code.
In Xcode you can indent one or more lines of code by selecting the source code you want to indent and then press the Command Key (⌘) + Right Square Bracket ( ] ).
To outdent that same source code press Command Key (⌘) + Left Square Bracket ( [ ).
On a larger scale if you have a whole block of source where the indentation is a mess (needing both indenting and outdenting), your best bet is to select the text you want to re-indent, right-click and from the pop-up menu select Structure > Re-indent
to have Xcode do all the indents and outdents for you.
Now, there’s one more thing I should point out before we move on and dive into the actual detail of what our main.m
file is doing, something that you probably won’t have picked up yet by looking at the contents of our main.m
file and that’s capitalization.
Objective-C is what we call a case-sensitive language. That means that if I had two things myThing
and mything
are not actually the same thing when it comes to Objective-C! Just keep this in mind as we move forward with learning the Objective-C programming language: capitalization and case is important.
Comments
Now lets start looking at what this file actually does. Look at the first seven lines of our source file are comments:
//
// main.m
// HelloiOSDevelopmentTutorials
//
// Created by Andy Bargh on 30/03/2013.
// Copyright (c) 2013 Andy Bargh. All rights reserved.
//
I’ve written a whole other post on the different types of comments that are available in Objective-C, you can take a look at it here: Objective-C Comments.
Importing and Header Files
Lets take a look at the next line of code in the main.m
file:
#import <Foundation/Foundation.h>
Can you guess what it does?
In Objective-C you have the ability to import source code from other source files.
Remember we talked about the process of linking in my post on the Four Phases of Implementing an Objective-C Program? Remember how I mentioned that you could use libraries within your own code? The Foundation Framework is one such library and is represented by the Foundation.h
file.
As you can see the Foundation.h file has a `.h` extension. This indicates that it is is a header file.
Header files are Objective-C source files that contain all the source code you need to make use of a particular library or source file from within another piece of code.
We’ll see more of header files elsewhere in this blog, but for now all you need to know is that in Objective-C, if you want to make use of a library or some other source code from within your own, you will need to instruct the compiler to include the header file for that library or source by adding the #import statement to your own code.
The #import
statement is an example of something called a pre-processor directive.
Pre-processor directives start with a #
(pound or hash symbol) and when you compile your source file, the compiler (or more accurately a component of the compiler called a pre-processor), looks through your source code for any of these directives and processes them before it attempts to compile your source code. This allows you to modify your code in advance of it actually being compiled.
There are a number of pre-processor directives available in Objective-C, (many of which I’m sure we’ll come across during the course of this blog), but in the case of the #import
statement this specific directive instructs the compiler to substitute the contents of the Foundation.h
file into your source file in place of the directive itself.
The benefit of the import
directive is that it doesn’t do this blindly. In the underlying C Programming language the equivalent pre-processor directive to import, a directive called include
, has the potential to suffer a serious problem, something called recursive includes. In the case of the import directive, recursive includes are avoided by the import directive instructing the compiler to check, as part of its pre-processing, whether it has already included a reference header file and if it has, it simply ignores the directive.
Search Paths
Now, we’ve looked at what the #import
part of our line is all about, lets take a look at the back and of that line, the part from the starting angle bracket ( < ) up to and including the ending angle bracket ( > ).
As we’ve talked about above, this section of the include statement specifies the header file of the library that you wish to include within your own source file. We tell the compiler exactly which file we want to import by using something called a path specification.
Now there are two types of path specification that you can use in Objective-C; the angled bracket form that we can see here and a quoted form (one with double quotes rather than the angle brackets). Their difference is subtle.
If you use the angled-bracket form of the path specification with our #import statement, as we can see in our example program below:
#import <Foundation/Foundation.h>
That tells the compiler to look in its standard list of system directories for that particular file. This is usually used for referring to the header files for libraries that have been supplied along with the Objective-C language.
The following line however:
#import "myfile.h"
Well, that tells the compiler to first search for the indicated file within the directory containing the current file and then in its own list of standard system directories. As I said, the difference is subtle, but given the fact that the compiler will stop searching once it has found the referenced file, you can see how it gives you the ability to not only direct the compiler where you want it to search but also allow you to substitute your own versions of the header system files should you so wish. We’ll come back to that in later posts when we look at testing, but for now lets move on.
The main( ) Function
The next seven lines in our main.m file define the main function:
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
Functions
A function is a named block of code between curly braces that define a set source code statements. Every Objective-C program consists of one or more of these functions and every Objective-C program must contain a function called main
.
The main
function is a special function in an Objective-C program in that it indicates where an Objective-C application begins its execution. When you execute your application, the operating system will search for the main
function within your application and start from there. The main
function can then call other functions which can call other functions and so on to perform whatever functionality you want in your application.
Lets look at the first line of our main
function.
int main(int argc, const char * argv[])
This is called the function prototype and specifies the functions return type, function name and parameters.
Return Types
At the beginning of the function prototype is the return type. In this case the int
reserved word indicates that the function returns an integer value when it finishes executing. If our function didn’t return anything we would replace the int
keyword with the keyword void
.
If we quickly jump forward to line 14:
return 0;
This is where execution of the main function actually returns. The return
statement in this case indicates that the main function should return an integer value of 0 (zero). The convention is that a return value of 0 (zero) from the main
function indicates execution was successful and any other value indicates something went wrong.
If we had declared that our function as not returning a value at all (by declaring a return type of void
) we would in turn completely omit this return
statement.
Now lets go back to the declaration of our main
function.
Function Names
After the return value is the function name, which in this case is, as you know by now, called main
.
Function names are the names used to refer to the blocks of code defined between the opening curly brace (line 9) and closing curly brace (line 15). They really come into their own when you start using them to invoke the source code within other functions. We’ll see more of this elsewhere in this blog.
Parameters
After that we then have two, comma separated parameters between open and closing parentheses.
Parameters are placeholders used to pass information (also known as arguments) into a function.
When a function is invoked, the arguments, the actual values supplied for each parameter, can be used by the source code within the function either as part of the functions operation (such as performing some sort of calculation) or as a way to return information from the function.
Each parameter has a datatype that indicates the type of data that should be supplied for that parameter (int
or const char *
in this case), followed by the name of the parameter (argc
or argv
). Source code within the function can then access the attributes supplied to the function by referring to the parameter names.
Note: We’ll ignore the two square brackets after the argv
parameter for now. This indicates that the argv
parameter is in fact an array of const char *
data. Arrays are something I’ll explain in another post.
Lets move on.
Next up is line 10 which uses a special Objective-C keyword called @autoreleasepool
to start a new block of code:
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
See the opening and closing curly brackets that mark the beginning and end of the block? Autorelease pools are a way of managing the computer memory used to create things (a.k.a. objects) within your Objective-C program. I’m planning a separate post on memory management at some point in the future.
NSLog
Now you should already know what line 11 does (yes it’s another inline comment) so the next line of interest to us within this program is line 12. Lets take a quick look:
NSLog(@"Hello, World!");
This is our first example of a function actually being invoked or called in Objective-C.
Unlike when you declare a function, when you call one, you do not need to specify the return type for the function. Return types are only written when you declare a function not when you call it. As a result, the first thing that we see on this line is the name of the function that we want to call, in this case a function called NSLog
.
The NSLog
function allows you to log a message using Apples System Logging Facility, and it is this line that results in the console output we saw in the previous tutorial.
The NSLog
function is declared in the Foundation.h
file we imported earlier (now you see the reason we imported that file), and takes one or more parameters of type NSString
. As this is likely the first time you’ve been exposed to Strings, lets take things slowly. First, what is a string?
Strings
A string is nothing more than a sequence of characters. You can use them to label things, represent names or, as in our example, print them to the console. In the C Programming language strings are implemented through a sequence of characters terminated by a null character (‘/0
‘).
An example of a C string would be something like the following:
"Hello, World!"
Notice that the double quotes surrounding it? This indicates the string is a string literal, the string is literally used and displayed as it is written.
In Objective-C you can still use these C strings but the Foundation Framework provides an enhanced version called NSString
.
The attribute supplied in the call to the NSLog
function is an example of an NSString
. Notice the difference? The @
symbol before the double quotes? This is used to indicate that the string is an NSString
rather than a C string.
Semicolons
The final item on line 12 is the semi-colon. As with the C programming language, program statements in Objective-C are terminated with a semicolon (;). Forgetting the semi-colon on a program statement is a common mistake so keep an eye out for this when you start writing Objective-C of your own.
Summary
So there we have it, our first Objective-C program top to bottom. In this post we took a look at the contents of the main.m
file and made some serious progress in understanding our first Objective-C. Join me next time as we build on that knowledge.
Photo credit: https://unsplash.com/photos/bt-Sc22W-BE