How To Make iPhone Apps – Object Oriented Programming and Classes

Welcome to my series on How To Make iPhone Apps with no programming experience – where we’ll turn even the non-programmer into an iOS developer! Here’s the article index for the entire series in case you missed it. In this article, we’re going through some basic but core programming principles that you’ll need to build… View Article
Written by

Chris C

Updated on

Sep 23 2019

Table of contents

    Welcome to my series on How To Make iPhone Apps with no programming experience – where we’ll turn even the non-programmer into an iOS developer! Here’s the article index for the entire series in case you missed it.
    In this article, we’re going through some basic but core programming principles that you’ll need to build iPhone apps.
    If you’re coming from another programming language, then chances are you could probably advance to the next article. Otherwise don’t worry, read on and welcome to the wonderful world of programming!

    1. Object Oriented Programming

    The common understanding that non-technical people have about programming and coding is that it’s a series of commands and statements that tell the computer what to do. (At least, for the sample of people that I’ve asked!)

    I never try to explain anymore than that because the explanation above works for them and that’s what they understand. That’s cool.

    But if we’re about to build iPhone and iPad applications, I’m afraid that we’re going to have to get a little deeper than that!

    The programming language we use to build iPhone and iPad apps is called Objective-C and it’s also a form of object oriented programming.

    I’m going to borrow from Wikipedia here:

    An object-oriented program may be viewed as a collection of interacting objects… In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects. Each object can be viewed as an independent “machine” with a distinct role or responsibility.

    Basically, the Wikipedia quote is saying that our program, or app, is just a bunch of objects interacting with each other.

    Each object is defined by a “blueprint” which describes the characteristics of that object. But the blueprint merely describes the object.

    In order to have an object with which we can use to perform tasks, we have to create an “instance” of it using the blueprint.

    Think of the blueprint as a plastic mould. By filling the mould with plastic and allowing it to cool, we can manufacture an instance of an object.

    When we’re building our iOS app, we’re essentially defining a series of blueprints for our objects, telling the program to create instances of objects and then issuing commands and statements for the objects to perform tasks and interact with other objects.

    Got it? I know you got it.

    Onward!

    2. So What Is A Class?

    You already know what this is.

    It’s just the correct term for the “blueprint” that we’ve been talking about! So from now on, I’m going to say “class” instead.

    In Objective-C, a class is defined with two files; a “.h” file and a “.m” file. There are various names for these two files, but we’ll stick with what Apple uses in their documentation. The .h file is called the “header” file while the .m file is called the “source” file.

    So for example, if I were intending to write a class for a Superhero, I would have Superhero.h and Superhero.m.

    The header file is where we tell other classes that interact with our class exactly what sort of interaction is available. You can think of the header file as a sort of public description of the class.

    In Superhero.h (the header file), I would state what sorts of variables, properties and methods are available for other objects to interact with my Superhero. (More on variables, properties and methods farther down).

    The source file however is where you implement the “guts” of the Class. This is where all of the code and logic of your Class goes.

    In Superhero.m (the source file), I would write the code for what happens if another object actually called upon the variables, properties and methods that I defined in Superhero.h (the header file).

    I want to remind you that the header file and source file, together, define a class and that a class is simply a “mould” or a “blueprint”. In our programming later on, we’ll be able to create instances of our class which we call objects. And we’ll make these objects interact with each other.

    A few paragraphs ago, I mentioned that we use the Header file to specify what sorts of interactions our class would permit. I hinted at variables, methods and properties, so let’s take a closer look at what those are!

    3. Variables To Store Things

    You can think of a variable as a bucket to store a value of some sort. Once you declare a variable, you can set its value and retrieve it later on when you need it.

    However, you must define the type of value that a variable can store and it can only store values of that type. You can even specify other classes as the type that you’d like to store!

    Variables are essential to our programming because we’ll need to keep track of different objects, values and other data. We will keep track of this stuff by declaring variables of the correct type and we’ll use variables to help us keep track of these objects, values and data.

    When we declare a variable in a class, your intention is probably to store some data that is related to that class.

    In our Superhero.h file, we might declare a variable to identify and store our Superhero’s intelligence, stamina etc. Or we might even declare a variable with a type Superhero, in order to refer to our Superhero’s superpal!


    What type of variables are there?
    There are two broad categories of variables: value types and reference types. Then there are a whole bunch of variable types that fall into one of these two categories. Any variable which keeps track of objects is a reference type and the other ones are value types.

    The good news is that this variable type terminology doesn’t vary too much from language to language (in terms of programming languages).

    The bad news is that if this is the first time you’re seeing this, the variable type names won’t seem very intuitive to you!

    Here are some of the common ones you’ll be using:
    NSString
    int
    BOOL
    double
    [Classname]

    NSString
    With this variable type, you’ll be storing string data. In other words text! In most programming languages, text is thought of as a “string of text”, thus the variable type “string”. In Objective-C, it’s “NSString”. The extra “NS” is just something that Apple denotes their own classes with, so you’ll be seeing it again and again with other Apple classes.

    NSString is an Apple class, so remember that instances of classes are objects and variables that keep track of objects are reference-type variables. Later on, you’ll see that when we declare reference type variables, we’ll denote it with an additional asterisk (*) that we don’t have with value type variables.

    int
    “int” stands for integers. Did I just bring back memories from high school Math? 🙂
    With this variable type, we store whole numbers. This is a value type variable.
    BOOL
    “BOOL” stands for boolean and this variable type can have only one of two possible values. “YES” or “NO”.
    You can also assign it “TRUE” or “FALSE” or “1” and “0” but it means the same thing.

    You might be thinking, couldn’t we just represent this with a string or int type variable? You’re right, but if you know that the data you’re storing could only be one of two values, then by using a BOOL you would save memory and make your code less error-prone.

    This is a value type variable.

    double
    With this variable type, we store decimal numbers.

    This is a value type variable.

    Classname
    I mentioned above that you can specify a class name as a variable type. When you specify a classname as your variable type, you can assign to that variable, an object of that class.

    This is a reference type variable.

    Other types
    There are way more variable types to introduce but let’s not get overwhelmed. We’ll introduce more as we need them. Let’s talk about methods!

    4. Methods To Do Things

    Think of methods as actions that we can call on to make an object do something. We define a method by giving it a name, what sort of variables we expect as input, what sort of result we will output at the end of the method, and finally the actual code and logic inside of the method!

    When we declare a method in the header file of a class, we’re saying that other objects will be able to use these methods on instances of our class. You’ll be declaring your methods in the header file and writing the code to carry out the method in the source file.

    In our Superhero example, I might declare a method called “Punch” in Superhero.h. In doing so, I’ll need to write the code in Superhero.m to make the Superhero object do something when the punch method is called.

    5. Properties, What?

    A property is sort of a variable and a method combined.

    What??

    OK, OK. I know it’s confusing but think of it this way:

    A property is a method that sets or retrieves the value of a variable.

    Well, then you might ask, “Why would I need a property if I can have variables that I can set or retrieve values from?”.

    Well, you usually use a variable to keep track of something that you will use within your class. If your intention is to expose it for other classes to be able to set and retrieve, you’ll want to use a property.

    Under the hood, a property still uses a variable to store the value you assign to the property.

    In fact, it’s a best practice to declare a property for something that you want other classes to be able access or interact with.

    This brings us to another point:

    6. Public Versus Private

    So far, we’ve been talking as if everything was public but when you declare something, you need to consider the scope of it. Should that method really be accessible for everyone? Should that variable be exposed to only my class or to everyone?

    When a variable or method is declared as private, other objects won’t be able to set/retrieve those variables or call on those methods of your class. In fact, they won’t even know about them.

    Only the code that you write within the source file can use the private variables and private methods. Other classes won’t be able to.

    When would you want to use private?
    For methods and variables that aren’t anyone else’s business, you can use the private keyword to limit the access to them. This eliminates some guess-work when it comes to debugging your application and trying to see why some variables don’t have values that you expect them to have because you can rule out the possibility of other objects changing the value. If it’s a private variable, you know that it can only be changed by the code in that same class.

    No one is stopping you from making everything public but it’s a good practice to limit the scope of your variables and methods if they don’t need to be public.

    Now what kind of iPhone app development tutorial would this be without examples? Let’s jump right into some Objective-C code implementing the stuff we talked about earlier in the article!

    7. Defining A Class In Objective-C

    Let’s re-use our Superhero example.

    When we create a new class, we have the header file (.h) and source file (.m).

    The header file in Objective-C
    Here’s what our header file will look like:
    Superhero.h

    // Imports are necessary to let this Class know about 
    // the names, variables, methods and properties of other Classes
    #import 
    
    // This is the declaration of our Superhero class
    // it inherits from NSObject (more on this below)
    @interface Superhero : NSObject
    
    // Right now, we haven't specified any properties, methods or variables
    
    @end
    
    A Comment About Comments:

    The green text that’s specified with “//” is a comment. Comments are just statements for the developer to leave remarks for himself or other people reading their code. It won’t affect anything.
    Anything after “//” is considered a comment.
    If you’ve got a large block of text you want to mark as comment, you can wrap it with “/*” and “*/”. Anything between those two tags will be considered a comment.

    In our header file, there’s an import statement and that’s basically to let this Superhero class know about other classes and their respective header file.

    Remember, a header file tells other classes what variables, methods and properties are available with your class. So if your class wants to refer to stuff in another class, you have to import their header file.

    In this case, we’re importing the Header file of some core Apple classes.

    Next, you also notice something beside the name of our class. What is this “: NSObject”?

    This is another object oriented programming concept called Inheritance.

    8. About Class Inheritance

    Not in the sense of money, but in every other sense, Superhero is going to “inherit” all the methods, properties and variables of a class called “NSObject”.

    For example, if I was going to create a Spiderman class and I noticed that my Spiderman and Ironman class had a lot of methods or properties in common, I could create a Superhero class that had the commonalities, and then get both my Spiderman and Ironman classes to inherit from the Superhero class.

    This is good because I won’t have to write duplicate code and in both my Spiderman and Ironman class and now if I wanted to change something in that common method or property, I only have to change it in one place (in the Superhero class) rather then in two places.

    Superhero Tip: Always try to reuse code wherever you can!

    Anyways, we got a little side tracked! But that was a really important concept to understand.

    Onto the source file!

    The source file in Objective-C
    Here’s what our Implementation file will look like:
    Superhero.m

    #import "Superhero.h"
    
    @implementation Superhero
    
    @end
    

    By default, your source file will have an import statement for your header file or else it wouldn’t know what variables, properties or methods to implement!

    9. How To Declare And Use Variables In Objective-C

    We have to give Superhero some stats right? Let’s declare some variables in our Superhero class to keep track of them.

    Superhero.h

    #import 
    
    @interface Superhero : NSObject
    {
        int _agility;
        int _strength;
        int _intelligence;
        BOOL _hasLasers;
        NSString *_greeting;
    }
    
    @end
    

    In the code above, we’ve defined several integers to keep track of vital statistics (lines 5-8).
    We’ve defined a boolean variable to keep track if our Superhero currently has lasers or not.
    And finally we’ve declared an NSString variable to track a piece of text that we’ll use as our Superhero’s greeting message later.

    Remember what we talked about earlier regarding scope. These variables are private because they’re declared within the curly braces underneath line 3 and we want them that way. If we want to expose something that another class would be able to set and retrieve, we use properties.

    Why did we put an underscore in front of all of our variable names? This is a common naming convention to easily distinguish variables that are private. A naming convention is a system or standard that you follow to name all of your variables, methods and properties so that they are consistently named and the code throughout your app is nice, neat and orderly.

    Programmers like things neat and orderly. It’s logical!

    10. Declaring And Using Properties In Objective-C

    If we wanted to declare a property for our class so that other classes could access it, we would declare it in the header file like this:

    Superhero.h

    #import 
    
    @interface Superhero : NSObject
    {
        int _agility;
        int _strength;
        int _intelligence;
        BOOL _hasLasers;
        NSString *_greeting;
    }
    
    @property (nonatomic, strong) NSString* Name;
    @property (nonatomic) int Stamina;
    
    @end
    

    Notice in line 13, we’ve declared a property. There are a couple of key things to note here.

    First of all, we’re always going to start with “@property”.

    Next, we have two keywords “nonatomic” and “strong”. Let’s talk about “nonatomic” first.

    In order to understand what nonatomic means, you have to understand that when we’re writing code we can specify some commands to run in another thread. Thus, you can have parts of your code running and executing in parallel! At some point, those other threads that you sent off to do some work will return to the main thread.

    Now imagine if multiple threads are trying to set and retrieve the property of an object simultaneously. This can lead to unexpected behaviour and most likely app crashes!

    By default, your property will be “atomic”. What this means is that there will be some overhead added to your code to implement an object-level lock which will prevent that from happening. Imagine that your property is a nightclub and there’s a bouncer in front of your property, ensuring that each thread waits in line to set the property! This is what programmers call “thread-safe”.

    So alternatively, if we specify “nonatomic” for our property, that means we’re saying that we don’t need the extra overhead to make our property thread-safe. Maybe because we don’t anticipate multiple threads setting it at the same time, or maybe we’re not using multi-threading in our code.

    Ok, so now, what about “strong”? Again, i’ll have to defer to the section on Memory further below!

    Next up, we have the property Type. Same thing as specifying a variable type; we want to tell others what type of values this property can have.

    And the last part is giving a name to the property. This will be the name that other classes will access the property by.

    How would you access or set a property of an object in Objective-C?
    Let’s say you had a variable called mySuperhero of type Superhero, that was keeping track of a Superhero object.
    You could set the value of a property like this:

    mySuperhero.Stamina = 9;
    

    This would put the value 9 into that objects stamina property.

    And to access that value, you would just say write something like this:

    int stamina = mySuperhero.Stamina;
    

    This would assign the value 9 to the variable stamina.

    11. How To Declare And Use Methods In Objective-C

    And now we arrive at how to declare methods.

    Remember that declaring a method involves specifying a method name, the types of variables it expects as input the variable type that it is expected to output and a scope for the method.

    Let’s say we wanted to declare a method for our Superhero named “Fight” with the intention of attacking our super villains.

    We would declare it in the Header file like this:

    Superhero.h

    #import 
    
    @interface Superhero : NSObject
    {
        int _agility;
        int _strength;
        int _intelligence;
        BOOL _hasLasers;
        NSString *_greeting;
    }
    
    @property (nonatomic, strong) NSString* Name;
    @property (nonatomic) int Stamina;
    
    - (int)Fight:(int)enemyStamina;
    
    @end
    

    On line 15, we’re declaring the Fight method. Let’s break this down.

    The dash “-” (yes even the dash means something!) signifies that this is an instance method. This means that you can call this method on an instance of this class. It relates to a specific instance of an object of this class type. This it the scope of the method.

    The alternative is a “+” which means that this is a “Static” method. We don’t need to know about that now, so let’s move on to the next part.

    The “(int)” part is the return type of the method. What’s inside the brackets tells us what type of value we can expect to be returned. In this case, it’s “int” meaning that we’ll expect an int value to be returned as the result of this method. This is the return type of the method

    The return value could also be “void”. As in, there is no expected value to be returned. This method will take some input and perform some action but will not return any value. However, don’t try to use the keyword, “void”, as a variable type, because you can’t. It doesn’t make sense!

    The following part is the method name, “Fight”. Other classes will call this method by this name.

    If our method didn’t accept any parameters, that would be it. However, in our example, we have a colon “:” followed by “(int)enemyStamina”. The colon is always followed by a parameter and in our example, the method expects a single parameter as input and it should be of type int. The parameter name, “enemyStamina”, should give some indication as to what that parameter represents; in this case, the enemy’s health! These are the parameter(s) of the method. (Note: Later on in Part 2, you’ll see how to declare a method with multiple parameters).

    Finally, the semi-colon at the end of the line tells us that is the end of that statement.

    Together, all these elements form the method signature.

    We’re not done yet! So far, we’ve defined the method in the Header file but we’ve still got to implement the method in the Implementation file. That is, write the code for the method to actually do what it’s suppose to do!

    In Superhero.m, it’ll look like this:

    #import "Superhero.h"
    
    @implementation Superhero
    
    - (int)Fight:(int)enemyStamina
    {
        int resultingStamina = enemyStamina - 5;
        
        return resultingStamina;
    }
    
    @end
    

    In the Implementation file, you’ll notice that the method signature looks exactly the same as it does in the header file however, there is a block of code inside curly braces right below it. This is where we write the code for this method.

    We’ve got two lines of code. On line 7, we’re declaring a new variable of type int called “resultingStamina” and we’re also assigning a value to it. We’re assigning the value of the int parameter that is passed in, minus five. So if the enemyStamina that is passed in has a value of 9, the resultingStamina variable will contain 4.

    In line 9, we “return” the variable resultingStamina as the resulting output for the method. Notice that the variable type of the variable we’re returning matches the return type of the method we specified in the Header file! The return keyword is reserved for specifying or “returning” the expected method output.

    How would you call the method on a Superhero object? Well, let’s say you had a variable called otherSuperhero of type Superhero, that was keeping track of an Superhero object.

    You would call the Fight method like this:

    int resultingHealth = [otherSuperhero Fight: mySuperhero.Stamina];
    

    Whoa, there are so many things happening in this statement! First of all, we’re calling the Fight method of otherSuperhero.

    Secondly, the Fight method needs an input of int value type remember? So we’re passing in the value in the stamina property of another Superhero object called mySuperhero.

    Finally, we’re taking the result of the Fight method and assigning it to the variable resultingHealth.

    What would the value of resultingHealth be?

    If you remember above in the property section, we set mySuperhero.Stamina = 9, right?

    So since the Fight method takes that value and subtracts 5 from it, the value in resultingHealth will be 4.

    12. Instances, References And Memory (not the kids card game!)

    I’m not referring to that old card game you used to play as a kid where you have all of the cards face down and you try to flip over two of the same card. I’m talking about computer memory!

    Your iPhone only has a limited amount of memory. Every object you create will use up some of that memory and when you’re done with that object, it gets destroyed and the memory it took up gets freed to be used for something else.

    To make things even more complicated, there are two types of memory, Stack and Heap. The stack is for value type variables and the heap is for reference type objects.

    To give you a visual representation of the stack, imagine it like a stack of books. When you allocate memory, you put a book on top of the stack. If you wanted to free memory, you would take the top book off first. This is called LIFO, or last-in-first-out. The last one in, is the first one out like in our stack of books analogy.

    With a heap, think of it like a row of mailboxes, each box having its own address. When we allocate memory on the Heap, a mailbox gets picked and the actual object resides in the mailbox.


    So this brings us back to the notion of instances of our class. Remember, our class is just a mould or blueprint that we use to create instances of objects of that class. And it’s the actual objects that will interact with each other.

    Here’s what a statement to allocate an object looks like:

    Superhero *instanceOfSuperhero = [[Superhero alloc] init];
    

    Let’s talk about the statement as a whole. That statement is creating an instance of the Superhero class by allocating memory for it on the Heap, then calling the method “init” on it and finally the variable *instanceOfSuperhero is being assigned the address of the allocated object.

    Did you get that?

    When we call alloc on our classname, it returns an instance of that class and then we call the init method on it which initializes the class and returns the same object. The init method is where we can set default values for variables and do anything else we need to get the object ready for use.

    Because objects are always allocated on the Heap which is addressed based, whenever we declare a variable to keep track of it, the variable doesn’t actually store the object. The variable is actually a pointer to the memory location of the object (or the mailbox in our analogy before). We denote this by adding the asterisk (*) in front of the variable name.

    Any variable that refers to an object holds the memory location of the object, and NOT the object itself. If multiple variables are keeping track of an object, each of those variables is basically holding an address to that object.

    Reference counting
    Because there’s a limited amount of memory available to your application, if you allocate and create too many new instances of objects, you could hit that limit (bad things will happen to your app. iOS will probably close it!).

    It’s important that we dispose of the objects we no longer need or use and free up the memory for other uses. The good thing is that you don’t have to manually do this. In iOS 5.0+, this is handled by ARC (automatic reference counting).

    So how do we know when an object is no longer needed?

    This is where reference counting comes into play. Each object has a count of references to it. The idea is that if there are no variables referring to it, chances are it won’t be used anymore. If a variable is keeping track of an object, then there’s a chance that it could be used.


    Remember when we declared our property earlier on? I told you that I’d explain what “strong” meant. Basically, “strong” means that if the property referencing an object, it will increase the reference count of that object. The alternative to “strong” is “weak”.

    If you specify “weak” when you declare your property, it doesn’t increase the reference count of the object so there may be a chance that the object becomes deallocated and the memory is freed, even if you still have a reference to it via your property. Later in the series, we’ll realize when we use “weak”, but usually we will want a “strong” reference to the object.

    Let’s Summarize

    If you’ve gotten this far into the post then you deserve a huge pat on the back! That was a lot to absorb and we introduced many programming concepts but you’re well underway in your journey to build iPhone and iPad apps!

    Below is a recap the main concepts we went through. See if you can recall the main points of each topic as you move down the list. If anything is fuzzy in your memory, I recommend you to give this article another read! On the other hand, if you breezed past this material and want to go deeper into understanding these topics, you can visit the Apple Objective-C Primer.

    -Classes and class inheritance
    -Variables and variable types
    -Methods
    -Properties
    -Public vs private
    -How to define a class in Objective-C
    -How to declare and use variables, methods and properties in Objective-C
    -Memory allocation and reference counting

    What’s next?

    In the next part of this series, you’ll dive right into code! We’ll talk about control structures and data structures.

    Go To Part 2

    Let’s improve this article together!

    I want to make this series and this article in particular the best and easiest to understand resource for beginners to learn how to develop iPhone apps. If you’ve got any feedback, good or bad, please let me know via the comments below so I can update parts which are confusing, add more examples and to continue updating this resource.

    And if you’ve enjoyed this article or you know someone who might be interested in learning how to build iOS apps, please share this series with them. It’s targeted at the non-programmer (sort of like an iPhone application development for dummies book) so anyone you know will be able to pick this up and progress towards developing iPhone apps!



    Get started for free

    Join over 2,000+ students actively learning with CodeWithChris
    6 Shares
    Share
    Tweet
    Pin
    Share
    Buffer