Objective C- 6 Days

download Objective C- 6 Days

of 37

Transcript of Objective C- 6 Days

  • 7/30/2019 Objective C- 6 Days

    1/37

    OBJECTIVE - C CLASSES

    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 withObjective-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 byObjective-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 andencounter any problems then be sure to leave a comment and I ll see if I can help.

    http://developer.apple.com/http://developer.apple.com/http://developer.apple.com/http://developer.apple.com/http://developer.apple.com/http://developer.apple.com/
  • 7/30/2019 Objective C- 6 Days

    2/37

    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.

    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:

    1. 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:

    1. 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 arent 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:

    1. gcc inputfile.m -o outputfile

  • 7/30/2019 Objective C- 6 Days

    3/37

    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:

    1. ./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: Im not slacking off. My code iscompiling.

    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:

    1. #include

    2. int main(){

    3. printf("Hello World\n");

    4. return 0;

    5. }

    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.

    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:

  • 7/30/2019 Objective C- 6 Days

    4/37

    1. gcc program1.m -o program1

    Your program should compile with no errors. To run it, simply type:

    1. ./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 weimported 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:

    1. 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:

    1. 123 + i = ?

  • 7/30/2019 Objective C- 6 Days

    5/37

    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:

    1. #include

    2. int main(){

    3. int someNumber = 123;

    4. printf("My number is %i \n", someNumber);

    5. return 0;

    6. }

    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 ifstatement. An if statement does what it sounds like, it checks

    to see if something is true, then acts either way. For example:

  • 7/30/2019 Objective C- 6 Days

    6/37

    1. #include

    2. int main()

    3. {

    4. if(1 == 1) { // This is always true

    5. // Do some stuff here

    6. }7.

    8. return 0;

    9. }

    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:

    1. int main(){

    2. if(1==1){

    3. // Do some stuff here.

    4. }

    5. else{

    6. // The universe is broken!

    7. }

    8.

    9. return 0;

    10. }

    Of course, in real life, we wouldnt 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 lets 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:

  • 7/30/2019 Objective C- 6 Days

    7/37

    1. // if loop

    2. int main () {

    3. int i = 9;

    4. int x = 0;

    5.

    6. for (x = 0; x < i; x++){7. printf("Count is: %i\n", x);

    8. }

    9.

    10. return 0;

    11. }

    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 oneeach time, x will soon no longer be less than i and the loop will finish and the program will

    carry on running.

    1. // while loop

    2. int main () {

    3. int x = 0;

    4. while (x < 10){

    5. printf("Count is: %i\n", x); //Watch OUT! Something is missing.

    6. }

    7.

    8. return 0;

    9. }

    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:

    1. // while loop

    2. int main () {

    3. int x = 0;4. while (x < 10){

    5. x++;

    6. printf("Count is: %i\n", x);

    7. }

    8.

    9. return 0;

    10. }

    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:

  • 7/30/2019 Objective C- 6 Days

    8/37

    1. // do loop

    2. int main () {

    3. int x = 0;

    4. do {5. x++;

    6. printf("Count is: %i\n", x);

    7. } while(x < 10);

    8.

    9. return 0;

    10. }

    Pointers

    Pointers can cause a lot of confusion with newcomers to programming or just newcomers toC. 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:

    1. int foo = 123; // This is an integer variable

    2. 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.

  • 7/30/2019 Objective C- 6 Days

    9/37

    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.

    Any Questions

    If you have any questions, you can either leave a comment below where I ll try and keep

    checking or you can shoot me a message on Twitter (http://www.twitter.com/iDemonix)

    where I ll get back to you ASAP.

  • 7/30/2019 Objective C- 6 Days

    10/37

    Welcome to part two of this introductory series on Objective-C. After spending last week

    reviewing the fundamentals of the C language upon which Objective-C is built, this week we

    will transition to focusing on what makes Objective-C such a great language for software

    development. Specifically, we will discuss the fundamentals of Object Oriented Programming

    (OOP) and demonstrate how to create a class and send messages to objects in Objective-C.

    Object Orientated Programming

    Why do we have Objective-C? Why not just use the underlying C language? The reason we

    have Objective-C is to give us an object oriented playground within which to build our

    applications. OOP is a programming paradigm that attempts to allow developers to think

    about software design in terms of objects and attributes instead of variables and functions.

    Specifically, OOP attempts to obtain data abstraction, encapsulation, modularity,

    polymorphism, and inheritance. The topic of OOP could easily fill a book (or a tutorial series)

    on its own, so instead Ill introduce you to the basic principles by way of example.

    Imagine that you have a car. You can think of your car as an object. There are many other cars

    in the world and you might even own more than one. Your car has various properties to it:

    make, model, color, engine type, and many more. In Object Oriented Programming terms, we

    would call the abstract concept of a car a class and the individual car that you own an object

    or instance (instantiated object) of the class. When a new car is manufactured, a new instance

    of the car class is instantiated (or created) and given its own set of properties.

    Still a little fuzzy? Another great analogy is that of the cookie and the cookie cutter. The class

    is the cookie cutter, and the object is the cookie.

    So, why think in terms of objects? One of the best reasons is because this is how your brain

    naturally conceptualizes life in the real world, and there are many benefits to being able to

    abstract software development in similar terms.

    Classes (and hence objects) are made up of methods and attributes. If you come from another

    programming language, you may be more familiar equating methods with functions and

    attributes with variables. We will discuss each in turn next.

    Methods

    So we have an instance of a car, now that what do we do with it? Well, we drive it and fill itwith petrol, among other things. Driving and filling with petrol apply only to the cars that we

    use, meaning that when we fill up a car or drive a car, we are only impacting one instance,

    and not all the cars in the world. Therefore, filling up the car instance is considered an

    instance method. It s something we do to our instance and only our instance.

    On the other hand, if we ask the original car class how many colors of car are available, this is

    a class method because we are no longer only talking about the car we drive around but all

    cars in general.

    Many of these principles become more clear with use, so let s look at a little bit of syntax.

  • 7/30/2019 Objective C- 6 Days

    11/37

    In Objective-C, we call object methods by passing messages. When we want to know how

    much gas is in our instance of car, then we send a message to our instance and the message is

    the method we want to apply. Programmatically it looks like this:

    1. [recipient message];

    The brackets indicate we are sending a message. The first parameter is who should receive

    this message and the second parameter is what the message actually is. Finally, we end with a

    semi-colon as is common to most programming languages.

    So, with our previous example in mind, this is how we would interact with our instance of car

    to add gas to the tank;

    1. [dansCar addGas];

    The example above assumes that we have instantiated an instance of the Car class and named

    it dansCar. We then pass the addGas message to the object dansCar, which is theequivalent of calling a function. In another language, this line might look like:

    1. dansCar.addGas();

    Attributes

    Let s say our car class has a gas tank that s stored as a percentage. For example, if the gas

    tank is at 50% then it is half-full and if it is at 100%, it means it is full to the brim. Now, if we

    want to know how much gas is in the tank, we don t just directly take that information from

    an attribute. Instead, we would use an accessor method to access the internal variable for us.Likewise, when we want to fill the tank, we don t just give the gas tank attribute a new

    percentage, we use a setter to update the attribute for us. This process is known as data

    encapsulation.

    What we mean by data encapsulation is that data is contained (so to speak) by methods

    meaning to access it we need to use methods. Some of you who have programmed in other

    languages and haven t heard of data encapsulation may be wondering why we do things this

    way. The answer is that by encapsulating data, there is a nice cushion between the developer

    of a class and the user of a class. Because the class methods manage and maintains the

    attributes within the class, they can more easily maintain data integrity. Another major benefit

    is that when a developer distributes his class, the people using it don t have to worry about the internals of the class at all. A developer may update a method to make it faster or more

    efficient, but this update is transparent to the user of the class as he/she still uses the same

    method with no change to his/her code.

    This brings us nicely on to the next section we re going to look at, which is how Objective- C

    separates interface from implementation.

    Interface and Implementation

  • 7/30/2019 Objective C- 6 Days

    12/37

    When you create or work with a simple class in Objective-C you will see that it, by default,

    has two files. One is the implementation file which is a file that ends with a suffix of .m and

    the interface file which is a file that ends with a suffix of .h.

    Interface

    1. #import

    2.

    3. @interface Car : NSObject {

    4.

    5. //This is where attributes go

    6. float fillLevel;

    7.

    8. }

    9.

    10. //This is where methods go

    11. - (void)addGas;

    12.

    13. @end

    14.

    First of all, we re importing Cocoa.h which is a standard library with a lot of reusable code

    that we can use inside our app.

    Next, we re declaring that this is the interface for the Car, but we re also putting NSObject

    into that declaration. Adding : NSObject means that the Car class inherits from theNSObject class. Well talk more about inheritance in a future tutorial.

    Our instance variable fillLevel is declared next, and we specify that it is of the float data

    type so we can easily represent a percentage.

    The next line declares our addGas method. The - indicates that this is an instance method,

    not a class method. The (void) portion means that the method will not return anything back

    when it finishes executing. If the class was going to return an integer, this would be changed

    to (int) and the same for any other data type. Finally, we finalize the method declaration

    with a semicolon.

    Implementation

    1. #import "Car.h"

    2.

    3. @implementation Car

    4.

    5. -(void) addGas {

    6. // code goes here to add gas

    7. }

    8.

    9. @end

  • 7/30/2019 Objective C- 6 Days

    13/37

    The implementation in this case contains the method to add gas to the tank. We also import

    Car.h, which is the interface file. Where our addGas method sits, we could add many more

    methods, but todays scope is to simply get you to understand how classes work rather than

    make a fully-fledged class.

    Next Time

    Next time we ll be looking more in depth at methods and at using variables with methods (as

    well as the basics of managing variables in Objective-C). This tutorial wasnt too long as it s

    often a bit confusing for new developers as to why we separate classes in to more than one

    file. If you re feeling at all confused then please re-read the above or ask questions in the

    comments section below. Classes will be a constant reoccurrence in this series and it s

    important you understand how they work.

    Challenge

    Seeing as this part of the series was fairly theoretical, there s not too much you can do to

    practice. However, I do recommend this week that you sign up for Apple s developer website

    as it s an invaluable reference. Once you ve done that, have a snoop around some of their

    downloadable classes and download a few simple ones. You don t need to understand all of

    the code, just look at how the classes are formed and separated across files.

  • 7/30/2019 Objective C- 6 Days

    14/37

    Welcome to part three of this series -I hope you re enjoying it! Last week we looked at how

    we separate classes in to separate files (interface and implementation), this week we re going

    to look at classes again, but a little bit more in depth. We ll also take a peak at inheritance

    and how it works, along with variable scope.

    So far, we have had some great feedback via email, twitter and comments. It s great to see so

    many people are interested in this subject and it s even better to see that so many of you are

    trying it out for yourself and asking some great questions. Keep it up!

    In Review: Classes & Objects

    Let s review what we have learned about classes in this series so far. If you don t know any

    of this, feel free to skim back to the last tutorial to re-cap. Ok, so, what are classes?

    A class is a collection of encapsulated data and custom methods. A class may hold manydifferent kinds of data, and the class methods usually (but not always) perform action related

    to that data. In Objective-C, a class is usually composed of two files: an interface file and an

    implementation file. The interface file uses the .h file extension by convention and is where

    the person using the class can quickly find the methods and data members available to the

    class. The implementation file uses the .m file extension by convention and is where the

    majority of the code resides because it contains the actual implementation of all the functions

    declared in the interface.

    So, what makes a class different from an object? What is an object? An object is an instance

    of a class. Think back to our example with the car in the last part of the series. Where car is

    the class, then myCar, dansCar, and yourCar would all be objects because they areinstances of the car class.

    Classes from Apple (and some history)

    Before we carry on, I d like to share a few (of many) common classes you ll be using a lot

    that are provided by Apple, but first a quick history lesson.

    Many classes Apple provides are prepended by the abbreviation NS, which stands for

    NextStep. When Steve Jobs left Apple, he founded NeXT, creating workstation computers

    that ran on its operating system. The object orientated programming language used on thosemachines was called NeXTSTEP, which is where we get the NS from. When Apple

    acquired (another history lesson in itself) NeXTSTEP, they decided to base Mac OS X on

    NeXTSTEP.

    Here are some simple, common classes we ll see a lot of:

    NSString is a string of text that is immutable.

    NSMutableString is a string of text that is mutable.

    NSArray is an array of objects that is immutable.

    NSMutableArray is an array of objects that is mutable.

    NSNumber holds a numeric value.

  • 7/30/2019 Objective C- 6 Days

    15/37

    We ll learn many more later on, but for now the above will come in handy. You re probably

    wondering what mutable and immutable means, which is an entirely reasonable question. If

    an object is immutable that means when we create the object and assign a value then it is

    static. The value can not be changed. If an object is mutable then it is dynamic, meaning the

    value can be changed after creation.

    Pointers and Initializing

    Let s say we want to make a static string of text and log it, how would we go about it? In our

    code it would look something like this:

    1. #import

    2.

    3. int main (int argc, const char * argv[]) {

    4.

    5. NSString *testString;6. testString = [[NSString alloc] init];

    7. testString = @"Here's a test string in testString!";

    8. NSLog(@"testString: %@", testString);

    9.

    10. return 0;

    11.

    12. }

    I created this file in XCode by going to File > New Project > Mac OS X > Application >

    Command Line Tool > Type: Foundation (quite a journey!) and editing the implementation

    (extension: .m) file in the project.

    There are quite a few things here that are new, so let s examine the above piece by piece.

    First of all, we import the foundation library (this is because we set type to Foundation in the

    new project window before).

    1. int main (int argc, const char * argv[]) {

    This declares the initial function that will be called when our program begins execution. The

    two parameters separated by a comma are for passing arguments to our application. For now,

    don t worry about these as we won t be needing them right now.

    1. NSString *testString; testString = [[NSString alloc] init];

    We now create a pointer to an NSString object called testString. Once the first line of this is

    finished, no string exists yet, only a pointer to a string that we have not yet created. On the

    next line, we create the string our pointer points to.

    We could have alternatively written the last line like this;

    1. testString = [NSString alloc];

    2. [testString init];

  • 7/30/2019 Objective C- 6 Days

    16/37

    This may seem a little confusing at first. In the first version, we have nested the statements

    within brackets on the same line, whereas in the second we have separated the statements into

    two lines. The method init initializes all the instance variables in the class.

    1. testString = @"Here's a test string in testString!";

    This line is pretty self explanatory, the reason we prepend the quotes with an @ sign is to tell

    the compiler that the following text is an NSString.

    NSLog(@testString: %@, testString);

    Here we log some information to console. XCode has a debugger built in that you can find

    under the Run menu. It is very useful when developing an application to log when events are

    happening and the values of certain variables it can help when troubleshooting your

    application and debugging problems. This method works like printf (remember from the first

    week?) where we supply a string of text with a replacement character (%@ means an

    Objective-C object).

    Finally we return 0, which we know just tells the operating system that the application ended

    with no problems.

    Inheritance

    Remember when we made our NSString earlier, we used the init method? Well

    NSMutableString, NSArray and in fact, every single NS class, also uses init. Seems a lot of

    wasted code to put the init method in each class, right? It would be, that s why init is usually

    only implemented once, in the root class known as NSObject. Because classes inherit from

    each other, a class that is created as a child of another, parent class will automatically gain

    access to the parent class methods.

  • 7/30/2019 Objective C- 6 Days

    17/37

    Let s take NSMutableString for example. NSMutableString has NSString for a parent

    (making it a child), meaning it inherits from NSString. Meanwhile. NSString has NSObject as

    a parent, so it inherits from NSObject.

    So for example, NSObject has a method called init, so each subclass has this method

    implemented which is called a class method. As a matter of fact, the init method in

    NSObject doesnt actually do anything it simply returns self. The reason for this is that

    methods can be overwritten. So the NSArray class may override the init that it inherits to add

    functionality to it such as making sure memory is available or preparing any instance

    variables it may need.

    As demonstrated, this is useful because it means that in addition to inheriting from classes we

    can also extend classes. When we extend a class, we take an existing class and add additionalfunctionality to what is already available. This means you could create your own version of

    NSString with additional methods, such as a method to fill the string with random text or

    perform some sort of character encoding.

    Summary

    At this point, the fundamentals of how classes work should be clear. To test your

    comprehension, see if you can answer the following questions in your mind:

    What is the difference between a class and an object? Why do we use classes?

    Why is inheritance useful?

    Since classes are such an important part of Objective-C, it s important to really feel

    comfortable working with them. Last week we started looking at classes and this week we

    have gone into more depth. Next week, you may be glad to hear, we re going to move away

    from the theoretical side and start working on our own simple class or two to perform simple

    tasks.

    Homework

  • 7/30/2019 Objective C- 6 Days

    18/37

    Since we have mainly done theory so far, your homework this week is to surf Apple s

    developer website (you should have done this last week) and look at some of the classes

    available. If you don t know where to start, start with something such as NSString. You ll

    become more comfortable with the details of the parent class, the methods, and so on. This

    will be important later on when you re using classes outside of this series and you want to

    know what methods they inherit or use.

    Next Time

    We ll get more practical next week with some class coding. Classes really are central to

    Objective-C, so it s mega important that you come to grips with them and the goal of this

    series is to really ensure that you do!

    As usual, if you have any questions or comments, you can reach me by dropping a comment

    or email. If you d like to get in touch with me personally and get a quick answer, send me a

    tweet!

    Welcome to part four of this series on Objective-C. So far, weve looked a lot at theory and

    the principles and functionality of the language to get a good idea of how it works. Today, we

  • 7/30/2019 Objective C- 6 Days

    19/37

    will be making a simple class similar to the car example we looked at in previous parts of this

    series. Our class will take the details of a car, allowing us to get and set the values held. After

    todays example you should be able to create your own classes in Xcode and toy around with

    them.

    So far, we have had some great feedback via email, twitter and comments. It s great to see so

    many people are interested in this subject and it s even better to see that so many of you are

    trying it out for yourself and asking some great questions. Keep it up!

    Getting Started

    Start by firing up Xcode and creating a new project. Under the Mac OS X separator, click

    Application, then click Command Line Tool. Finally, change the drop down box to set the

    type to Foundation.

    Save the project as whatever you want, I called mine CarApp. Once the project window

    appears, we need to create a new class. Hit Command-N (or File > New File), navigate to

    Cocoa Class under Mac OS X and select Objective-C class. Make sure Subclass of is set to

    NSObject and press Next. Name your class SimpleCar and ensure that a .h file will be

    created, then save it.

  • 7/30/2019 Objective C- 6 Days

    20/37

    Our class now exists, but it does nothing. Lets change that by giving it some code.

    Remember that in Objective-C we split our code into two parts: interface and implementation.

    It makes logical sense to work on the interface first, so thats where well start.

    Coding the Interface

    Open up the SimpleCar.h file and in its current state it should look like this (Ive omitted the

    comment header from below)

    1. #import

    2.

    3. @interface SimpleCar : NSObject {

    4.

    5. }

    6.

    7. @end

    First of all, were including Cocoa.h, which gives us access to such things as NSString,

    NSMutableString, etc. Then, we create our class (SimpleCar) as a subclass of NSObject.

    Now we need to decide on what information our class needs to store. Since were using a car

    as our example we need to store car-related information, such as:

    Make

    Model

    VIN

    Theres a lot more we could go into, but for now that will do. For each of these properties, we

    need to store them in a variable suited for that type of data. Make and model will be a range of

    characters (such as text, number and possibly punctuation) so it makes sense to use a string.

    The VIN (Vehicle Identification Number) will only be a number so thats what well use. Our

    code now looks like this (header omitted):

    1. @interface SimpleCar : NSObject {

    2. NSString* make;

    3. NSString* model;

    4. NSNumber* vin;

    5. }6.

    7. @end

    We previously said that in order to get or set data from a class, a method should be used. So to

    set the variables, we need to add methods. To do this, well make four: one will set the make,

    one the model, one the VIN, and a final method will set both make AND model (just to show

    you how to use multiple arguments).

  • 7/30/2019 Objective C- 6 Days

    21/37

    1. @interface SimpleCar : NSObject {

    2. NSString* make;

    3. NSString* model;

    4. NSNumber* vin;

    5. }

    6.7. // set methods

    8. - (void) setVin: (NSNumber*)newVin;

    9. - (void) setMake: (NSString*)newMake;

    10. - (void) setModel: (NSString*)setModel;

    11.

    12. // convenience method

    13. - (void) setMake: (NSString*)newMake

    14. andModel: (NSString*)newModel;

    15.

    16. @end

    We declare methods after the curly bracket and before @end. By placing a dash (minus sign)

    before the method, we tell the compiler were about to declare an instance method. An

    instance method is a method executed on our instance. Conversely, a plus sign indicates that

    the method being invoked is a class method that does not need an individual object instance to

    execute -more on this later.

    Our first method returns void, is called setVin and takes an NSNumber as an argument. Our

    second method is similar, it returns void, is call setMake, and takes an NSString as an

    argument. The third is the same, with a different name.

    Our final method also returns void but takes two parameters: newMake and newModel, both

    of which should be NSString. The naming used in this method is similar to how most

    Objective-C methods are named: in plain English. So when you read the method allowed its

    obvious that the method will Set make and model. Its important to remember that the

    method name in this case is setMake:andModel: all the argument titles are included in the

    method name.

    An important note is that we use (void) because our methods do not need to return anything.

    Since all they are doing is setting data and do not need to return anything back (such as a

    success message) we simply use void.

    Next, we will add the methods we will use to get the values. Although we call our methods

    get and set methods, we only usually use set in the title and omit get. How you name your

    methods is ultimately up to you, but dropping get is common and helps avoid confusion.

    Our new set of methods looks like this:

  • 7/30/2019 Objective C- 6 Days

    22/37

    1. // set methods

    2. - (void) setVin: (NSNumber*)newVin;

    3. - (void) setMake: (NSString*)newMake;

    4. - (void) setModel: (NSString*)newModel;

    5.

    6. // convenience method7. - (void) setMake: (NSString*)newMake

    8. andModel: (NSString*)newModel;

    9.

    10. // get methods

    11. - (NSString*) make;

    12. - (NSString*) model;

    13. - (NSNumber*) vin;

    Notice that the get methods use the same names as the variables in the class. This will make it

    simple when we fetch the variables. It will be as if were accessing the variables directly,

    essentially making the get methods appear transparent.

    Coding the Implementation

    So now that the interface is in place and we know what the class will do, we need to

    implement our methods. Looking back, we have four methods we need to implement: setVin,

    setMake, setModel and setMake:andModel. Before we move files, copy the method

    declarations to your clipboard (Cmd+C). Now close SimpleCar.h and fire up SimpleCar.m in

    the editor, pasting the method declarations in between the @implementation and @end, like

    so:

    1. @implementation SimpleCar

    2.

    3. // set methods

    4. - (void) setVin: (NSNumber*)newVin;

    5. - (void) setMake: (NSString*)newMake;

    6. - (void) setModel: (NSString*)newModel;

    7.

    8. // convenience method

    9. - (void) setMake: (NSString*)newMake

    10. andModel: (NSString*)newModel;

    11.12. // get methods

    13. - (NSString*) make;

    14. - (NSString*) model;

    15. - (NSNumber*) vin;

    16.

    17. @end

    Obviously this isnt right, so what we need to do is swap the semi-colons for curly brackets

    where the inner workings of the method will go, like this:

  • 7/30/2019 Objective C- 6 Days

    23/37

    1. @implementation SimpleCar

    2.

    3. // set methods

    4. - (void) setVin: (NSNumber*)newVin {

    5.

    6. }7.

    8. - (void) setMake: (NSString*)newMake {

    9.

    10. }

    11.

    12. - (void) setModel: (NSString*)newModel {

    13.

    14. }

    15.

    16. - (void) setMake: (NSString*)newMake

    17. andModel: (NSString*)newModel {18.

    19. }

    20.

    21. // get methods

    22. - (NSString*) make {

    23.

    24. }

    25.

    26. - (NSString*) model {

    27.

    28. }

    29.

    30. - (NSNumber*) vin {

    31.

    32. }

    33.

    34. @end

    Now we need to give our methods some code. Lets start with the getter methods as theyre

    straightforward enough. For each getter method, all we need to do is make sure that the

    function returns what it is intended to return. For this reason, our getter methods look likethis:

    1. - (NSString*) make {

    2. return make;

    3. }

    4.

    5. - (NSString*) model {

    6. return model;

    7. }8.

  • 7/30/2019 Objective C- 6 Days

    24/37

    9. - (NSNumber*) vin {

    10. return vin;

    11. }

    Remember: the methods are returning the variables we defined in the interface file. Dont get

    confused between the method names and the variable names.

    Thats pretty straightforward, when we call make (for example), then make returns the pointer

    to an NSString in this case to the make variable. The same happens for model and vin

    (except of course vin returns a number).

    Now for the setter methods, first well look at the code and then well go through it

    afterwards. Our setter methods look like this:

    1. // set methods

    2. - (void) setVin: (NSNumber*)newVin {

    3.4. [vin release];

    5. vin = [[NSNumber alloc] init];

    6. vin = newVin;

    7.

    8. }

    9.

    10. - (void) setMake: (NSString*)newMake {

    11.

    12. [make release];

    13. make = [[NSString alloc] initWithString:newMake];

    14.

    15. }

    16.

    17. - (void) setModel: (NSString*)newModel {

    18.

    19. [model release];

    20. model = [[NSString alloc] initWithString:newModel];

    21.

    22. }

    23.

    24. // convenience method25. - (void) setMake: (NSString*)newMake

    26. andModel: (NSString*)newModel {

    27.

    28. // Reuse our methods from earlier

    29. [self setMake:newMake];

    30. [self setModel:newModel];

    31.

    32. }

    The set methods are a bit trickier than our get methods. We want to alloc the values that are

    passed into each method so that they are owned by the class. We first release these variablesin case they are already allocd. If they are not allocd, then they are nil, and nil objects ignore

  • 7/30/2019 Objective C- 6 Days

    25/37

    messages passed to them. We will cover these issues more when we discuss memory

    management.

    Because we actually allocated memory for our objects in the setter methods, we need to be

    sure we release them when the object is released from memory. To do this, we need to add a

    custom dealloc method, like so:

    1. -(void) dealloc

    2. {

    3. [vin release];

    4. [make release];

    5. [model release];

    6. [super dealloc];

    7. }

    Testing the ClassCongratulations! If you followed everything above then you should now have a working class

    (if not, download the source files available with this article). So, lets test it out.

    Open up the main file of your project (mine is called CarApp.m) which by default should look

    something like this:

    1. #import

    2.

    3. int main (int argc, const char * argv[]) {

    4.5. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    6.

    7. // Insert custom code here...

    8. NSLog(@"Hello, World!");

    9.

    10. [pool drain];

    11. return 0;

    12. }

    Delete the comment and NSLog line as we wont be needing them right now.

    In order to begin using our class, we need to pull it into the program. Underneath the original

    #import line add the following line:

    1. #import "SimpleCar.h"

    Our class is now available for use, but we need to create an instance of it in order to test it out.

    Heres the code used in total:

  • 7/30/2019 Objective C- 6 Days

    26/37

    1. #import

    2. #import "SimpleCar.h"

    3.

    4. int main (int argc, const char * argv[]) {

    5.

    6. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];7.

    8. SimpleCar *myCar = [[SimpleCar alloc] init];

    9.

    10. NSNumber *newVin = [NSNumber numberWithInt:123];

    11.

    12. [myCar setVin:newVin];

    13. [myCar setMake:@"Honda" andModel:@"Civic"];

    14.

    15. NSLog(@"The car is: %@ %@", [myCar make], [myCar model]);

    16. NSLog(@"The vin is: %@", [myCar vin]);

    17.18. [myCar release];

    19.

    20. [pool drain];

    21.

    22. return 0;

    23. }

    First of all we create a pointer to an instance of SimpleCar called myCar. Next we use alloc

    and init these will be discussed later on down the line.

    Next, since we need to pass an NSNumber to the setVin method, we make one here. Again we

    create a pointer to an NSNumber instance called newVin and we initiate it with the integer

    value of 123. The constant 123 is an integer, which is why we use numberWithInt.

    Next, we invoke our methods, first of all we put who should receive the message (myCar) and

    then we use the method setVin. After the colon is the value we are supplying to the method

    which is the NSNumber we created before. Next we do the same but call the setMake method

    with two parameters. The reason these parameters are preceded by an @ sign is to tell the

    compiler that the following is a string.

    Finally, we release myCar as we are done with it more on this later in the series undermemory management.

    Our class is now working, and in order to see the proof, we added some NSLog statements to

    print the values to the console. If you open up the console (Run > Console) and then build and

    run your app, you should see output similar to this:

  • 7/30/2019 Objective C- 6 Days

    27/37

    Property and Synthesize

    If you look at the code above, a lot of it seems quite pointless and excessive. For example, in

    our getter methods all we are doing is returning an instance variable but this takes up three

    lines of code to do something simple. Also, in our setter methods, we are just setting instance

    variables essentially all of our methods, except our method that takes two arguments, seem

    bloated and in the way. Objective-C solves this with @property and @synthesize, which

    replace our accessor methods and make for much neater coding.

    This is what our new interface file looks like using properties:

    1. #import

    2.

    3. @interface SimpleCar : NSObject {

    4. NSString* make;

    5. NSString* model;

    6. NSNumber* vin;

    7. }

    8.

    9. @property(readwrite, retain) NSString* make;

    10. @property(readwrite, retain) NSString* model;

    11. @property(readwrite, retain) NSNumber* vin;12.

    13. // convenience method

    14. - (void) setMake: (NSString*)newMake

    15. andModel: (NSString*)newModel;

    16.

    17. @end

    18.

    Wow, that really is a lot shorter. So whats happening with the @property declarations? First

    we tell the compiler we are declaring a property by using @property, then we follow with

    attributes for this property. The attributes are the read/write status of a property and somememory management. We have used readwrite for all, which means getter and setter methods

  • 7/30/2019 Objective C- 6 Days

    28/37

    are dynamically created for our instance variables (we could of used writeonly or readonly for

    just one or the other). The reason we use retain will become clear next time when we cover

    memory management.

    Before this can work, we need to implement it in our implementation file, we do this using

    @synthesize. Our new implementation file looks like this:

    1. #import "SimpleCar.h"

    2.

    3. @implementation SimpleCar

    4.

    5. @synthesize make, model, vin;

    6.

    7. - (void) setMake: (NSString*)newMake

    8. andModel: (NSString*)newModel {

    9.

    10. [self setMake:newMake];11. [self setModel:newModel];

    12.

    13. }

    14.

    15. @end

    Doesnt that look better? Think of it like this, @property replaces all of the interface method

    declarations for getters and setters, and @synthesize replaces the actual methods themselves.

    The getters and setters are now dynamically created and we dont need to waste time creating

    them unless we need to do something really special.

    Wrapping Up

    You should now have a firm grip of classes, objects and instances. Sure, youre not creating

    classes that will change the world yet, but this stuff takes time. Its better to learn by example,

    so if youre not coding as you go along then be sure to at least download the source files and

    have a read through (and a compile) to ensure youre 100% on whats going on.

    Next Time

    Weve mentioned memory management a lot in this tutorial, its a very important subject that

    needs to be addressed (pun intended), so well dive in to that next time. True, it isnt the most

    fun subject or the easiest to come to terms with, but its absolutely crucial if you want to

    become a skilled Objective-C programmer.

    Challenge

    This weeks challenge may be a little tricky, but well see how you get on. First of all, if you

    havent copied all the code above, download the source files that are included with this article.

    The challenge is to add another class to the project, but this time it should be a subclass of

    SimpleCar (remember, we define the parent class in the interface file). If you can do that, play

  • 7/30/2019 Objective C- 6 Days

    29/37

    around and use the inherited methods and try to add your own for things such as: engine size,

    doors or height.

    Remember: if you have any questions or queries, drop a comment below or shoot me a

    message on Twitter. The only stupid question is the one you didnt ask this series is about

    learning so feel free to ask away!

  • 7/30/2019 Objective C- 6 Days

    30/37

    Welcome to part five of this series on Objective-C. Today were going to look at memory

    management, an element of Objective-C (and many other languages) that tends to trip up

    newer programmers. Most scripting languages (such as PHP) take care of memory

    managaement automatically, but Objective-C requires that we are careful with our use of

    memory and manually create and release space for our objects.

    Its good practice to keep track of how much memory your application is using, so you dont

    encounter any leaks or hog up the memory on the system. Its even more important on mobile

    systems such as the iPhone where memory is much more limited than on a desktop machine.

    Two Approaches

    In Objective-C there are two methods for managing memory, the first if reference counting

    and the second is garbage collection. You can think of them as manual and automatic, as

    reference counting is code added by the programmer and garbage collection is the systemautomatically managing our memory. An important note is that garbage collection does not

    work on the iPhone, which is why we will not look at how it works. If you should wish to

    program for the Mac, then its worth looking at Apples documentation to see how garbage

    collection works.

    Reference Counting

    So, how do we manage our memory in our apps? First of all, when do we use memory in our

    code? When you create an instance of a class (an object), memory is allocated and our object

    can now function correctly. Now one little object might not seem that great of a deal, but

    when your apps grow in size it quickly becomes an enormous problem.

    Lets look at an example, say we have some sort of drawing app and each shape the user

    draws is a separate object. If the user has drawn 100 shapes, then we have 100 objects sat in

    memory. Now lets say the user starts over and clears the screen, then draws another 100

    objects. If we dont manage our memory properly, were going to end up with 200 objects

    doing nothing more than hogging memory.

    We counter this by reference counting. When we create a new object and use alloc, our

    objects have a retain count of 1. If we call retain on that object, the retain count is now 2 and

    so on. If we release the object, the retain count decrements back to 1. Whilst the retain count

    is non-zero, our object will stick around, but when the retain count hits zero, the systemdeallocates our object freeing up the memory.

    Syntax

    There are various methods you can call that will have some effect on memory management.

    First of all, when you create an object using a method name that contains alloc, new or copy,

    you take ownership of that object. This is also true if you use the retain method on an object.

    Once you release, or autorelease (more on that later) an object, you no longer take ownership

    of that object or care what happens to it.

    So, if we alloc an object like so;

  • 7/30/2019 Objective C- 6 Days

    31/37

    1. myCarClass *car = [myCarClass alloc];

    We are now responsible for the object car and we must manually release it later (or

    autorelease it). Its important to note that if you were to try and manually release an object

    that has been set to autorelease, the application would crash.

    Since we created our object using alloc, our car object now has a retain count of 1, meaning it

    will not be deallocated. If were to also retain our object like so;

    1. [car retain];

    Then our retain count is now 2. So in order to get rid of the object, we need to release twice to

    set the retain count to 0. Since the retain count is now zero, the object will be deallocated.

    Autorelease and Autorelease Pools

    When youve created a new XCode project, you may have noticed some code that appears bydefault which creates an autorelease pool, up until now youve ignored it now were going

    to see what it does and where to use it.

    The code youre probably familiar with seeing by now should look like this;

    1. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    2.

    3. [pool drain];

    Note: if you refer to older documentation, you may see the last line as release, rather thandrain, this is a newer addition to the language but essentially does the same thing.

    By now you should be able to tell to some extent what the code above is doing; it is creating

    an instance of NSAutoReleasePool called pool, allocating memory for it and then initiating it

    using the init method.

    When we send the autorelease message to an object, that object is then added to the inner

    most auto release pool (inner-most because pools can be nested within each other more on

    that later). When the pool is sent the drain message, then all the objects sent the autorelease

    message are released, essentially autorelease is deferring the release until later.

    This is useful because many methods that return an object, typically return an autoreleased

    object, which means we dont have to worry about the retain count of the object we just got

    given, nor do we have to release it, as it will be done later on.

    Nested Autorelease Pools

    I spoke briefly before about the ability to nest autoreleased pools, but what use is that to us?

    Although there are several uses, one of the most common uses is to nest an autorelease pool

    inside a loop that uses temporary objects.

    For example, if you have a loop that creates two temporary objects to do whatever it is youwish, if you set those two objects to autorelease, you can use them until the pool is sent the

  • 7/30/2019 Objective C- 6 Days

    32/37

    drain message and not have to worry about manually releasing to deallocate. Apple have a

    great example of when youd use this kind of nested autorelease pool in their documentation;

    1. void main()

    2. {

    3. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];4.

    5. NSArray *args = [[NSProcessInfo processInfo] arguments];

    6.

    7. for (NSString *fileName in args) {

    8.

    9. NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];

    10.

    11. NSError *error = nil;

    12. NSString *fileContents = [[[NSString alloc] initWithContentsOfFile:fileName

    13. encoding:NSUTF8StringEncoding error:&err

    or] autorelease];14.

    15. /* Process the string, creating and autoreleasing more objects. */

    16.

    17. [loopPool drain];

    18. }

    19.

    20. /* Do whatever cleanup is needed. */

    21. [pool drain];

    22.

    23. exit (EXIT_SUCCESS);

    24. }

    The above example has a bit more than we need, but the structure is there. As you can see,

    when the application is opened and main is loaded, an autorelease pool called pool is created.

    Meaning anything autoreleased before the pool is sent the drain message will be assigned to

    this autorelease pool, unless it is inside an autorelease pool inside this one (sorry if that

    sounds a little confusing).

    Inside the loop, another autorelease pool is created called loopPool. This pool is drained

    inside the loop, so anything autoreleased inside the loop is released before the loop iterates (or

    ends).

    The inner autorelease pool has absolutely no effect on the outer autorelease pool, you may

    nest as many autorelease pools as you need. If we used autorelease in the loop above, but did

    not have a separate autorelease pool, then all the objects we were creating would not be

    released until the end of main. So if the loop ran 100 times, we would have 100 objects

    hogging up memory that have yet to be released bloating our application.

    retainCount

    Before we wrap up, lets look at something that could help make memory management an

    easier-to-swallow chapter. So far when weve created objects, weve remembered how many

    references an object has and so on but weve never seen an actual number. For the purposes

  • 7/30/2019 Objective C- 6 Days

    33/37

  • 7/30/2019 Objective C- 6 Days

    34/37

    In todays tutorial, you will learn about Categories and how to use them to extend the

    functionality of Cocoa-Touch classes. This is our final installment in the Learn Objective-C

    series, so you will also be provided with a quick recap on what weve covered so far and then

    look at what you can do to further your skills as an Objective-C or iPhone application

    developer.

    Categories

    So, what are categories? A lot of Objective-C tutorials and series will overlook categories,

    which is a shame as theyre such a useful language feature thats amazingly useful. Categories

    help keep code clean and less cluttered by eliminating the need for unnecessary subclassing.

    From what weve learned so far, if we had an NSString object that we wanted to add

    functionality to do something like add a method that would replace all the a characters with

    a 4 (useless I know, but for example purposes only), then we could subclass NSString and

    add the method ourselves. We also saw this kind of subclassing when we made our car class, Iasked you at the end of that tutorial to make a subclass of car so you could add functionality

    to the base class. Subclassing is a good approach, and I am in no way telling you to stop

    subclassing, but, in certain situations, categories provide a better approach to add some extra

    functionality to a class.

    Categories allow us to add methods to an existing class, so that all instances of that class in

    your application gain your functionality. For example, say we have 100 NSString objects in

    your app, but youd like to make a custom subclass so each NSString has an extra method

    (reverseString for example). With categories we can simply add the method in a category and

    all instances will be allowed to use the new method. The syntax is obviously slightly different

    from subclassing and categories dont allow you to use instance variables. However, it ispossible to overwrite a method already in place, but this should be done with caution and only

    if doing so is really necessary.

    Syntax

    Categories follow the same syntax layout as a class, as in they have an implementation and an

    interface. The interface looks like this:

    1. @interface ClassNameHere (category)

    2.3. // method declaration(s)

    4.

    5. @end

    6.

    7. The implementation looks like this;

    8.

    9. @implementation ClassNameHere (category)

    10.

    11. // method implementation(s)

    12.

    13. @end

  • 7/30/2019 Objective C- 6 Days

    35/37

    Example

    Easy, right? So lets look at an example. Were going to make a simple method that will

    reverse a string. While this method is practically useless; its not what the method is doing

    thats important. You should already know what the interface will look like, but here it is

    anyway:

    1. @interface NSString (reverse)

    2.

    3. -(NSString *) reverseString;

    4.

    5. @end

    Now to create our implementation:

    1. @implementation NSString (reverse)

    2.3. -(NSString *)reverseString {

    4.

    5. }

    6.

    7. @end

    Next, well need to add some simple code to flip the string around. Since were adding

    methods to the NSString class, we reference the string using self. Now in order to reverse the

    string well need a new, temporary string object to hold the reversed string. The way we will

    reverse the string is to simply loop through the existing string in reverse, each time we find a

    new character well add it to the reversed string object. The code for this is:

    1. int length = [self length];

    2. NSMutableString *reversedString;

    3.

    4. reversedString = [[NSMutableString alloc] initWithCapacity: length];

    5.

    6. while (length > 0) {

    7. [reversedString appendString:[NSString stringWithFormat:@"%C", [self character

    AtIndex:--length]]];

    8. }9.

    10. return [reversedString autorelease];

    This method is fairly simple, were looping through once for each character in the string. We

    append the current character using stringWithFormat and the character (C) identifier. When

    we call length we not only return the length integer, we also subtract from it too, which is

    how our loop moves along the string.

    If all has gone well then all NSStrings already in our project should adhere to our new

    category. Now you can see why categories are so useful!

  • 7/30/2019 Objective C- 6 Days

    36/37

    Using Our Example

    Ok, now all of our NSString objects should have our reverseString method. Just to recap, our

    code should look like this:

    1. @interface NSString (reverse)

    2.

    3. -(NSString *) reverseString;

    4.

    5. @end

    6.

    7. @implementation NSString (reverse)

    8.

    9. -(NSString *)reverseString {

    10. int length = [self length];11. NSMutableString *reversedString;

    12.

    13. reversedString = [[NSMutableString alloc] initWithCapacity: length];

    14.

    15. while (length > 0) {

    16. [reversedString appendString:[NSString stringWithFormat:@"%C", [self charact

    erAtIndex:--length]]];

    17. }

    18.

    19. return [reversedString autorelease];

    20. }

    21.

    22. @end

    Each block of code (interface and implementation) should be in their own respective files by

    convention. However, we name categories a little differently. The two files we have created

    are named: NSString+reverse.h (interface) and NSString+reverse.m (implementation).

    This is a typical naming convention following the pattern of the name of the class we are

    adding a category to, a plus sign, and the name of our category. Before we continue,

    remember that we still need to include our header file into the main project. So now our codeshould look something like this:

    1. NSString* testString = @"Just a test";

    2.

    3. [testString reverseString];

    4.

    5. NSLog(@"Reversed: '%@'", testString);

    If all went according to plan, then the Console should log a reversed version of Just a test!

  • 7/30/2019 Objective C- 6 Days

    37/37

    If all doesnt go according to plan, check to be sure youve copied the code for reverseString

    properly and make sure youre including the header (*.h) file for the category in your main

    code file.

    As you can see, categories really are quite useful (especially with strings). They have a wide

    range of uses in any project, a common one I use is validation. This way I can keep all of myvalidation in one place and dont have to use any complicated subclasses.

    Wrapping Up The Series

    Not only is this the end of todays tutorial, this is the end of the series on the fundamentals of

    Objective-C. Over the last several tutorials weve covered the following topics:

    Fundamentals of Programming

    Fundamentals of OOP

    Classes and Subclasses Memory Management

    Good Practice

    Some Standard Naming Conventions

    I hope youve enjoyed this series, and if youve only read one or two of the tutorials so far,

    then I encourage you to start at day 1 and read a tutorial a day. By the end of the series you

    should be confident enough to start writing your own code in just under a week!

    If you have any questions about the series or examples shown, or if you would like an

    additional tutorial on another area of Objective-C programming, feel free to leave a comment

    below.

    If you have any questions on Objective-C itself, a project that youre working on, or just some

    technical advice, dont hesitate to drop me a mention or direct message on Twitter or visit my

    website and find your way to the contact form!

    Challenge

    Now that were finished, the challenges are endless. I highly suggest you put pen to paper and

    decide on a first app to build from start to scratch. Come up with an idea and a design, then

    apply all the principles you have learned from this series and let us know what you come upwith!

    Thanks for reading!