Welcome to my series on coming to grips with the awesome language that is Objective-C. Throughout this small series of articles, my aim is to take you from no prior experience with Objective-C to using it confidently in your own applications. This isnʼt a rush job – so donʼt expect to just skim through the basics and be away – weʼll be going through not just the bare essentials, but also the best practices you can apply to ensure your code is the best it can be. Letʼs jump straight in!
What is Objective-C?
If youʼre reading this series then Iʼll hazard a guess that you already know, but for those of you who donʼt, donʼt worry as by the end of this part youʼll know what it is back-to-front and inside-out.
Objective-C is an object oriented language which lies on top of the C language (but I bet you guessed that part!). Itʼs primary use in modern computing is on Mac OS X as a desktop language and also on iPhone OS (or as it is now called: iOS). It was originally the main language for NeXTSTEP OS, also known as the operating system Apple bought and descended Mac OS X from, which explains why its primary home today lies on Appleʼs operating systems.
Because Objective-C is a strict superset of C, we are free to use C in an Objective-C file and it will compile fine. Because any compiler of Objective-C will also compile any straight C code passed into it, we have all the power of C along with the power of objects provided by Objective-C.
If youʼre a little confused at this point, think of it this way: everything C can do, Objective-C can do too, but not the other way around.
What will I need?
Throughout this series, we will not focus on building applications for the iPhone. Instead, we will concentrate more on the language itself and for this reason all you will need is a Mac with a compiler such as GCC. If youʼve installed the developer tools from Apple (Xcode, Interface Builder, etc), then GCC should already be installed. If not, then head to Appleʼs developer website and get yourself a free copy.
As far as prerequisites go, while I donʼt expect you to have a full background in computer science, some knowledge of programming in general or of C in particular would definitely be a bonus. If you donʼt have much prior programming experience, donʼt worry -youʼll pick it up in no time!
If youʼre running Windows (which is unlikely as this tutorial is aimed at iPhone developers) you can still compile Objective-C on your system using a compiler such as CygWin or MinGW. This tutorial series is catered to Mac users, but if you are using Windows and encounter any problems then be sure to leave a comment and Iʼll see if I can help.
Compiling your code
Before you can see your code in action, you need to be able to compile it into something executable. Hopefully you now have your copy of GCC ready. Compiling is really easy, a simple one line command.
NOTE:
Compiling is the process of “translating” a high-level computer language, like Objective-C or PHP, into a low-level machine code that can be processed by a computer when the program is executed.
Compiling is the process of “translating” a high-level computer language, like Objective-C or PHP, into a low-level machine code that can be processed by a computer when the program is executed.
All the programs that we see running in our fancy Mac OS operating system consist of a series of instructions that are visually displayed to us in a GUI, or Graphical User Interface. In contrast to the GUI program interaction with a mouse that most of us are familiar with, it is possible to issue commands directly to the operating system through a text-based interface known as a “terminal” or “command line.”
The command line application in Mac OS is called Terminal and can be found in Applications -> Utilities. Go ahead and open Terminal now (you can also search for it in Spotlight). Terminal has several basic commands you should be aware of in order to properly utilize it. One of the most important commands to know is cd, which stands for “change directory.” This command allows us to change where in the filesystem Terminal is reading from. We canʼt just tell Terminal to compile our file if we donʼt show it where the file is first! To switch to a desired directory, you can use a full path such as:
- cd /Users/MyName/Desktop/Test
You can also use relative paths, allowing you to only type a single folder name in some cases. For example, if youʼre already in your Desktop folder, you could simply type:
- cd Test
to get to the Test folder.
What if you want to see where you currently are? The immediate folder name is displayed before the prompt (the bit where you type). For example, if your prompt says Dan- Walkers-MacBook: Desktop iDemonix$ I can assume Iʼm in the Desktop folder. If you aren’t sure, you can also type pwd to display the absolute filepath of the current location.
If you want to list what files and folders are in the current folder, use the list command: ls. Finally, if you wish to go up a directory to a parent folder, type “cd .. “. So, if we were in the Test folder, which is inside the Desktop folder, but we wanted to go to the Desktop folder instead, we could type cd .. to go up to the parent directory, Desktop. If we wanted to get to the home directory we would type cd ../.. to go up two levels. Alternatively, to get to the home directory you can just type cd ~ from anywhere.
When using the Terminal application, compiling looks like this:
- gcc inputfile.m -o outputfile
Youʼve probably already guessed how it works: inputfile.m contains our code (.m is the extension used for Objective-C files) and -o tells gcc we want our executable to be called whatever we specify next, which in the example above is outputfile. To run our creation after compiling, we simply type:
- ./outputfile
Simple.
When you compile, the compiler will generate any errors, notifications or warnings related to the syntax of your code. Errors generated when compiling are understandably referred to as “compile-time” errors, and this is often the most stressful part of writing an application (especially when your code isnʼt compiling because you put a single character in the wrong place or forgot to end a line with a semi-colon). Compiling can also take time when youʼre writing large applications consisting of multiple files, which is also another reason why compiling can be a tedious experience. This fact has led to a ubiquitous programmer joke often seen on the t-shirts of men with unkempt beards: “I’m not slacking off. My code is compiling.”
The Basics
Objective-C itself isnʼt that hard to learn. Once you get to grips with the basic principles, you can pick the rest up as you go along pretty easily. You do need to have an understanding of the fundamentals of C programming though, and that is what the rest of this tutorial will cover.
Letʼs look at a basic application in C:
- #include <stdio.h>
- int main(){
- printf("Hello World\n");
- return 0;
- }
All this application will do when you run it is display the string “Hello World” in Terminal and exit.
NOTE:
Curious about the “return 0″ statement? Because we told the compiler that the function main() will return an integer, we return the constant integer value ’0′ at the end of the function. By convention, returning ’0′ signals to the calling program that our program finished execution without any errors.
Curious about the “return 0″ statement? Because we told the compiler that the function main() will return an integer, we return the constant integer value ’0′ at the end of the function. By convention, returning ’0′ signals to the calling program that our program finished execution without any errors.
To try this for yourself, fire up Xcode and make a new Objective-C class. Delete all the code Xcode gives you by default and stick the above code in. Once youʼve done that, you can compile it using Terminal. Open Terminal and change to the location where your file is, if you saved to the desktop then simply type cd desktop so that Terminal is now reading from your Desktop. Then type this command:
- gcc program1.m -o program1
Your program should compile with no errors. To run it, simply type:
- ./program1
Then hit return.
Awesome, so what actually happened there? Well, first we imported a library called stdio which manages the standard i/o (input output) functions, like printf(). We then create a function called main which should return an int or integer which is basically a number with no decimal point. We then use the printf() function to output ʻHello Worldʼ in to terminal. The \n we use tells Terminal to put a newline after the text. Finally, we return 0 (remember we said main should return an integer) which tells the operating system everything went fine. We use the name main because this is triggered automatically when the program is executed.
So far everything should be pretty simple: we wanted to write some text to Terminal, so we imported a library with a function for writing text, then we used a function from that library to write the text. Imagine that what you import is a physical library and printf() is one of the books available.
Variables
Soldiering ahead, weʼre now on to variables. One of the fundamental things we need to be able to do in our applications is temporarily store data. We do this using variables, which are containers that can hold various types of data and be manipulated in various ways. We use variables to store all sorts of data, but we must first tell the compiler what weʼre going to store in it. Here are several of the most important variables that you should know about for now:
- int – for storing integers (numbers with no decimal point)
- char – for storing a character
- float – for storing numbers with decimal points
- double – same as a float but double the accuracy
When weʼre not using variables, weʼre often using constants. A constant will never change: we always know what the value will be. If we combine constants we get a constant expression, which we will always know the result of. For example:
- 123 + 2 = 125
This is a constant expression, 123 + 2 will always equal 125, no matter what. If we substituted a constant for a variable, the new expression would look like this:
- 123 + i = ?
Because i is a dynamic variable, we do not definitely know the result of this equation. We can change i to whatever we want and get a different result. This should give you an idea of how variables work.
One thing we still need to know is how do we display variables like we displayed “Hello World” above? We still use the printf() function, except it changes a little this time:
- #include <stdio.h>
- int main(){
- int someNumber = 123;
- printf("My number is %i \n", someNumber);
- return 0;
- }
What weʼve done here is told the function printf() where we want our integer to appear, then where it can be found. This is different to a lot of languages such as PHP where you could just place the variable in the text.
We are not just limited to just one variable in printf(). The function can accept multiple parameters separated by commas, so we can pass in as many as we have formatting signs for in the text. Above we use %i as a formatting sign because we were including an integer. Other variables have their own format specifiers:
- %i – integer
- %f – float
- %e – double
- %c – char
One thing I want to touch on before we move on is the char type. A variable of type char can only handle single characters, when thatʼs all we need this is great, but if we need a string of text itʼs pretty useless. To get round this, we use something called a character array.
Imagine you have a sentence that is 11 characters long (like ʻHello Worldʼ – donʼt forget to include the space), a character array is like having 11 charʼs but all glued together. This means that the value of the character array overall is ʻHello Worldʼ but char[0] is ʻHʼ. In brackets is the char youʼre after, because we put 0 we get the first character. Donʼt forget that counting in arrays usually starts from 0, not 1.
Conditionals
When an application needs to make a decision, we use a conditional. Without conditionals, every time you ran your application it would be exactly the same, like watching a movie. By making decisions based on variables, input or anything else, we can make the application change – this could be as simple as a user entering a serial number or pressing a button more than 10 times.
There are a few different types of conditionals, but for now weʼre just going to look at the most common and basic: the if statement. An if statement does what it sounds like, it checks to see if something is true, then acts either way. For example:
- #include <stdio.h>
- int main()
- {
- if(1 == 1) { // This is always true
- // Do some stuff here
- }
- return 0;
- }
If 1 is equal to 1, then whatever is between the brackets is executed. You might also be wondering why we used two equals signs instead of one. Using two equal signs is an equality operator, which checks to see if the two are equal to each other. If we use a single equal sign then weʼre trying to assign the first value to the second value.
Above, since 1 will always be the same as 1, whatever is in the brackets would be executed. What if we wanted to do something if this wasnʼt true though? Thatʼs where else comes in. By using else we can run code when the if conditional returns false, like so:
- int main(){
- if(1==1){
- // Do some stuff here.
- }
- else{
- // The universe is broken!
- }
- return 0;
- }
Of course, in real life, we wouldn’t be checking to make sure 1 is the same as 1, but the point is made. Consider an application that closes if you press the close button three times (annoying but relevant). You could check in the brackets to see how many times it has been pushed. If it is lower than 3, then your else block could execute code to tell the user how many more times the button must be pushed to exit.
Weʼll look at conditionals more when we come to use them in our applications further along in the series.
Loops
Now let’s investigate a programming loop. Loops, as the name suggests, let us loop through a piece of code and execute it multiple times. This can come in very handy in situations such as populating a list or repeating a piece of code until a conditional returns true.
There are three types of loops, in order of most common: for, while, and do. Each one is used to repeat execution of a block of code, but they function differently. Here are examples of each:
- // if loop
- int main () {
- int i = 9;
- int x = 0;
- for (x = 0; x < i; x++){
- printf("Count is: %i\n", x);
- }
- return 0;
- }
This may look a little complex at first, but it really isnʼt. In the parentheses after for is the initiator, a conditional, and the action. When the for loop starts it executes the initiator, which in our case above sets x to 0. Each time the loop runs (including the very first time) it checks the conditional, which is "is x smaller than i?" Finally, after each loop through the code, the loop runs the action - which above increments x by one. Simple. Since x is increasing by one each time, x will soon no longer be less than i and the loop will finish and the program will carry on running.
- // while loop
- int main () {
- int x = 0;
- while (x < 10){
- printf("Count is: %i\n", x); //Watch OUT! Something is missing.
- }
- return 0;
- }
Similar to the for loop, the while loop will execute the code between the brackets until the conditional is false. Since x is 0 and we don't change it in the code block, the above would run forever, creating an "infinite loop." If you wish to increment x, then in the case of our while loop you would do this between the brackets:
- // while loop
- int main () {
- int x = 0;
- while (x < 10){
- x++;
- printf("Count is: %i\n", x);
- }
- return 0;
- }
The do loop is essentially the while loop, except the conditional runs after the block of code. What this means is when using a do loop, the code is guaranteed to run at least once:
- // do loop
- int main () {
- int x = 0;
- do {
- x++;
- printf("Count is: %i\n", x);
- } while(x < 10);
- return 0;
- }
Pointers
Pointers can cause a lot of confusion with newcomers to programming or just newcomers to C. It is also not immediately clear to some people how they are useful, but youʼll gradually learn this over time. So, what is a pointer?
As the name implies, pointers point to a location. Specifically, locations in computer memory. Think of it like this, when we create a variable (let's say it's an integer called ʻfooʼ as is so popular with programming theory) and give it a value of, for example 123, we have just that - a variable with a value of 123. Now, if we setup a pointer to foo, then we have a way of indirectly accessing it. That is, we have a pointer of type int that points to foo which holds the value '123.' This would be done in code like so:
- int foo = 123; // This is an integer variable
- int *ptr = &foo; // This is a pointer to an integer variable
Clear as mud? Donʼt sweat it. Pointers are hard - often considered the hardest thing to learn when picking up the C language. Pointers will eventually become second nature to you though, and there will be more on pointers within Objective-C further in this series.
Wrapping Up
You've just been given a crash-course overview of the C language fundamentals. This part of the series was intended to be a quick primer on C to get you ready and prepared for the rest of the series, and should have been especially useful to those who are already familiar with programming in another language. If you are new to programming in general or are still in doubt about any basic of C, re-read the above and feel free to leave questions in the comments.
Before next time, be sure to try and compile your own programs using the code above. Set yourself small challenges, such as making a loop execute 10 times and count each time through the loop using printf. Thereʼs no harm in trying and experimenting, if it goes wrong then itʼs probably even better as itʼll get you on the right track to troubleshooting your own code.
Challenge
For this week, we will end on a simple challenge. You are to create three programs that count to 10 using each type of loop. Since we will use loops often in Objective-C, itʼs good that you learn to create them by heart. That should be pretty easy, so try to count down from 10 to 1 afterwards (if ++ increments by one, what could be the code to decrement by 1?).
Next Time
In the next installment of this series, Iʼll provide an overview of how Objective-C works. Weʼll also look at object orientated programming and its uses, as well as really drill down into classes, instances, methods, inheritance and more.
Next week should really help you to understand what makes Objective-C such a great language and why it really extends the C language in so many useful ways.
No comments:
Post a Comment