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… 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. That explanation works, but if we’re about to build iPhone and iPad applications, we need 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.

    An object-oriented program may be viewed as a collection of interacting objects. In OOP, each object can receive messages, process data, and send messages to other objects. Each object can be viewed as an independent machine with a distinct role or responsibility.

    Basically, 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. The .h file is called the header file while the .m file is called the source file. 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, I would state what sorts of variables, properties and methods are available for other objects to interact with my Superhero. The source file is where you implement the guts of the class. In Superhero.m, 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 and source file, together, define a class and that class is simply a mould or 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.

    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 keep track of this stuff by declaring variables of the correct type.

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

    There are two broad categories of variables: value types and reference types. Any variable which keeps track of objects is a reference type and the other ones are value types.

    NSString
    With this variable type, you’ll be storing string data. In other words text. In Objective-C, text is stored as an NSString. NSString is an Apple class, so instances of NSString are objects and variables that keep track of objects are reference-type variables.

    int
    int stands for integers. 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, FALSE, 1, or 0, but it means the same thing.

    double
    With this variable type, we store decimal numbers. This is a value type variable.

    Classname
    When you specify a class name as your variable type, you can assign an object of that class to that variable. This is a reference type variable.

    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.

    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.

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

    For methods and variables that aren’t anyone else’s business, you can use the private keyword to limit access to them. This eliminates some guess-work when it comes to debugging your application.

    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.

    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 <Foundation/Foundation.h>
    
    // 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 in both my Spiderman and Ironman class. If I wanted to change something in that common method or property, I only have to change it in one place.

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

    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 <Foundation/Foundation.h>
    
    @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. 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.

    These variables are private because they’re declared within the curly braces underneath the interface declaration. 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. 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 <Foundation/Foundation.h>
    
    @interface Superhero : NSObject
    {
        int _agility;
        int _strength;
        int _intelligence;
        BOOL _hasLasers;
        NSString *_greeting;
    }
    
    @property (nonatomic, strong) NSString* Name;
    @property (nonatomic) int Stamina;
    
    @end

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

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

    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.

    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 object’s stamina property.

    And to access that value, you would 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 <Foundation/Foundation.h>
    @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

    The dash - signifies that this is an instance method. The alternative is a + which means that this is a static method.

    The (int) part is the return type of the method. In this case, we expect an int value to be returned as the result of this method. The return value could also be void, as in, there is no expected value to be returned.

    The following part is the method name, Fight. In our example, we also 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.

    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.

    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. The block of code inside curly braces is where we write the code for this method.

    We’re declaring a new variable of type int called resultingStamina and assigning it the value of the int parameter that is passed in, minus five. Then we return that variable as the method output.

    How would you call the method on a Superhero object? Let’s say you had a variable called otherSuperhero of type Superhero, that was keeping track of a Superhero object. You would call the Fight method like this:

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

    First of all, we’re calling the Fight method of otherSuperhero. Secondly, the Fight method needs an input of int value type, 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.

    If you remember above in the property section, we set mySuperhero.Stamina = 9. 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.

    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.

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

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

    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.

    When we call alloc on our class name, 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.

    Because objects are always allocated on the heap which is address based, whenever we declare a variable to keep track of it, the variable doesn’t actually store the object. The variable is a pointer to the memory location of the object. 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. It’s important that we dispose of the objects we no longer need or use and free up the memory for other uses. In iOS 5.0+, this is handled by ARC (automatic reference counting).

    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? Basically, strong means that if the property references 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 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