Chapter 2. Thinking like an iPhone developer

published book

This chapter covers

  • Model-view-controller
  • Object-oriented programming
  • Object lifetime

There’s only so much you can do with Xcode and Interface Builder without code, but before we get to Objective-C, you need to know more about how iPhone apps are structured. Once you understand that, it will be easier to understand how to code your app. Think of this as the part of The Karate Kid where Miyagi has Daniel painting fences and waxing floors. Or when Yoda makes Luke carry him through the swamps of Dagobah. Or maybe you’re more of a Sound of Music fan. If so, let’s start at the very beginning.

Using model-view-controller to dissect apps

When Maria danced through the streets of Salzburg with the von Trapp children, she taught them how to sing using the song “Do-Re-Mi.” Similarly, iPhone development can best be understood with the letters M-V-C. MVC, or model-view-controller, is a common way of thinking about apps and is used by web programmers, Windows and Mac programmers, and mobile app programmers (like us). It’s useful for any application that has a user interface.

Figure 2.1. MVC diagram

A model is anything in your app that isn’t related to the user interface. In applications that store data, models are used to represent the things that you store. For example, imagine a grocery list application where you keep track of everything that you want to buy, where it is in the store, and how much of it you need. A model can be used to represent the items you want to buy. Each item has a name (such as “Bananas”), the aisle (such as “Produce”), and the amount you want to buy (such as “One bunch”).

Figure 2.2. Model diagram

A view is what you see on the screen and interact with. When you draw sketches of iPhone apps or use Interface Builder, you’re drawing the view. To make things easier later, you keep each part of the user interface in a separate view. That means each button you click, text box you fill in, or check box you check is its own view. Views do more than just show the user what is going on—they’re also responsible for letting the rest of your application know they’re being touched. On that grocery list, the list you see is the view. Each item is in its own view, and when you touch the item to cross it off the list, its view is the part of the app that is first to know.

Figure 2.3. View diagram

A controller is where you coordinate everything. Your controller decides what to do when a button is clicked, when to show a different view, and what models should be changed. If you were to draw a flowchart of how your app works, a lot of that would be represented in your controllers.

Figure 2.4. Controller diagram

So, using a grocery list app example again, when you touch the Grocery Item View on your phone to indicate that you’ve put the item in your shopping cart, the view tells the Grocery Item View Controller that it’s been touched. The controller tells the model to remember that it’s been taken, and then it tells the view to show it crossed out.

The best way to learn MVC is to open apps on your phone and start seeing their features as models, views, and controllers. Every app on your phone can be broken down into these parts. You don’t have to do it this way, and your app will still work if you put something in the wrong place, but it’s much easier to understand and work on your application if you keep the components straight.

Thinking about apps as models, views, and controllers

Maria told us that once we knew the notes to sing, we could sing most anything. That applies to MVC and iPhone development too. Now that you know MVC, you know something about how every app is made. Again, they might not be made this way, but let’s not let that stop us.

Let’s look at one of the built-in apps on your iPhone. The easiest to understand is Calculator. Play with the app a little, and think about the kinds of things that are happening in it.

Figure 2.5. The Calculator app

The app starts by displaying a grid of buttons that have numbers and symbols on them. It also has a result area that starts with the number 0 in it. Let’s call the whole area of the screen the calculator view. It uses button views to draw buttons and a result view to show the result. Each view—the calculator view, button views, and result views—have to be able to draw themselves on the screen. To do that, they all need to know their position and size. Button views also need to know what text to show and what color they are. Position, size, content (such as text), and color are common things that views need to know.

Figure 2.6. Views used in the Calculator app

Once you’re running the app, several buttons are created, each with a location, a size, content, and a color. For example, the 7 button is near the left and about halfway down. It’s black. It has the number seven drawn on it in white, and it’s about the size of the tip of your finger. The Calculator app creates 22 button views on itself when it starts.

Now, click the 7 button. The result view displays 7. Click 3, and the result view now shows 73. Using what you know about MVC, here’s how it works.

Figure 2.7. How MVC works in the Calculator app

This continues as you push buttons. The model creates the numbers from the button presses and does the arithmetic, the view shows the answers and detects the touches, and the controller figures out what happens next.

This might seem complicated, but by doing this for larger projects, you can keep related code together. Also, by keeping views separate from logic in the models and controllers, you can change what the app looks like by replacing the views and keep the rest of the app the same.

Think that’s far-fetched? Turn your iPhone 90 degrees.

Turned 90 degrees, the app is still a calculator. There’s no reason why the models and controllers you created can’t be reused. By making sure the view of the app is separate, you can create an alternate view to use in landscape. Separation allows you to vary each part independently.

Figure 2.8. The Calculator app in landscape

A lot of apps come with the phone, so take a look at them. If you’re bored, download a game and goof off for an hour (we mean, figure out how MVC is used in it). When you’re done, take the test in the next section.

Test yourself on models, views, and controllers

These are some of the things the various apps that come with your iPhone do. Would the code for the feature be in the model, the view, or the controller?

Table 2.1. Test yourself

App feature

Model, view, or controller

1. In the Clock app, the current time is found in a ...  
2. In the Photos app, when you resize a photo by pinching it, your pinch is detected by a ...  
3. In the Photos app, when you swipe a photo, the app interprets that to mean to go to the next photo. The code for that is in a ...  
4. To unlock your phone, you need to slide a ...  
5. In the Contacts app, your best friend’s name and phone number are stored in a ...  
6. In the Calendar app, the current date is drawn in blue by the ...  
7. In the Calendar app, when you touch the right arrow, the ... decides to go to the next month.  
8. In the Phone app, when you click a contact, the ... dials the phone for you.  
9. In the iPod app, the titles of the albums are found in a ...  
10. In the Weather app, the sun and rain icons are shown in a ...  

If you’ve done well on this pop quiz, you’re ready to learn more about a broader concept called object-oriented programming. If not, it might be a good idea to reread this section, because understanding MVC is essential to understanding how iPhone apps are organized. When you’re ready, go get a snack. You deserve it.

Breaking down your applications to models, views, and controllers is a start, but there are two more concepts that will help get you from there to an iPhone app. The first is understanding how the various parts of your apps communicate with each other, and the second is understanding how to take each part (whether it’s a model, a view, or a controller) and break it down further. To do that, you need to learn about object-oriented design and message passing. Let’s get started.

Designing apps with objects

When Steve Jobs was between his two Apple stints, he headed a company called NeXT. Apple acquired NeXT and used its software as a basis for Mac OS X, Xcode, Objective-C, and much of what makes up the system software for Apple’s products. In 1994, while still at NeXT, Jobs did an interview with Rolling Stone where he extolled the virtues of object-oriented programming, a style of programming he saw at Xerox on the same day he first saw the graphical user interface. Here is an excerpt from that interview.

Would you explain, in simple terms, exactly what object-oriented software is?

Objects are like people. They’re living, breathing things that have knowledge inside them about how to do things and have memory inside them so they can remember things. And rather than interacting with them at a very low level, you interact with them at a very high level of abstraction, like we’re doing right here.

Here’s an example: If I’m your laundry object, you can give me your dirty clothes and send me a message that says, “Can you get my clothes laundered, please.” I happen to know where the best laundry place in San Francisco is. And I speak English, and I have dollars in my pockets. So I go out and hail a taxicab and tell the driver to take me to this place in San Francisco. I go get your clothes laundered, I jump back in the cab, I get back here. I give you your clean clothes and say’ “Here are your clean clothes.”

You have no idea how I did that. You have no knowledge of the laundry place. Maybe you speak French, and you can’t even hail a taxi. You can’t pay for one, you don’t have dollars in your pocket. Yet I knew how to do all of that. And you didn’t have to know any of it. All that complexity was hidden inside of me, and we were able to interact at a very high level of abstraction. That’s what objects are. They encapsulate complexity, and the interfaces to that complexity are high level.

When your app is running, each piece, whether it’s a model, a view, or a controller, is an object. As Steve Jobs described, each has memory inside it and a list of messages it understands. To use an object, you need to have access to it and to send it a message. It will do the work associated with the message and provide a result. Most messages need you to provide something along with them. In the laundry example, your dirty clothes are what you provide to the message, and the result of the message is the bag of clean clothes. The things you provide are called arguments or parameters, and the result is called the return value.

To describe what an object can remember and what messages it understands, you create a class in Xcode. It can be confusing to remember the difference between classes and objects. Just remember that classes are what you write in Xcode. They’re the blueprints. Xcode takes those blueprints and creates an app. When you run the app, it creates the objects that are the “living, breathing things” that make the app do something. Multiple objects can be made from the same class. For example, most of the button objects you see in an app are made from one class.

To help keep things straight, in diagrams in this book, classes will be in rectangles and objects will be in circles. Here are the parts of a class.

Figure 2.9. Classes

You create classes in Xcode to describe the objects that will do what you want your app to do. In your class, you define the messages that each object will be able to understand and what it needs to remember. But objects need to collaborate in order to get their work done. To do that, you need to connect them.

Establishing class relationships

If objects are living and breathing, they’re going to want to get into relationships with each other. This is an important part of object-oriented programming, because without knowing another object, you can’t send a message to it. Our job, as programmers, is to make introductions, help the objects make small talk, convince them to form longterm relationships, and then, eventually, help them break up.

The weakest relationship is the uses-a relationship. All this means is that in some way, one class uses another class. Usually, one of its messages takes a class as an argument or returns a class. Or it could be that while doing the message, a class needs temporary access to an object of the other class. If that’s the only way two objects are related, we show that with a dashed arrow, like so:

Figure 2.10. uses-a relationship

The next type of relationship is has-a, which we represent with a closed arrowhead. Sometimes it’s important to see other details, like how many of another object each object has and what that object calls the other object it has. If you don’t see a number by the arrowhead, you can assume the object has only one of the other object.

Figure 2.11. has-a relationship

The has-a relationship means the class could be considered an integral part of the one that has it. For example, a person has eyes, or a car has wheels. Or it could be that one class just has to keep track of another, like the way a person has a car. In the latter case, the has-a relationship can be mutual—the person has a car, and the car has an owner.

The most intimate relationship is is-a. This is a special relationship that means one class can perform every message that another one can, plus more. In addition, the class can choose to change the messages so that each message can do more. This is allowed as long as the changed messages do everything that the original message promised it would do. We represent this relationship with an open arrowhead. We won’t use it as much as the other relationships, but the iPhone SDK uses it all the time. You saw this type of relationship with views earlier. Buttons, tables, and labels are all views, so they remember everything that views remember and handle all messages that views handle. This relationship is also called inheritance, and the class is said to inherit its parent’s or superclass’s messages. If the message is changed in the child, or subclass, that is called overriding the message.

Figure 2.12. is-a relationship

These diagrams show you how classes are related, which tells you which messages they can send. What’s more interesting is to know which messages they do send. This is something that happens when the app is running, so it involves the objects, not the classes. We can use a diagram like the one on the next page to show the objects and the messages they send to each other.

To understand this diagram, the first thing to notice is what the objects are that are represented by individual circles. To get your laundry done, you send a message to a Launderer, and behind the scenes, they use a Cabbie and a Laundromat. Each arrow represents a message being passed, with the arrow starting at the object that passes the message and pointing to the object that receives the message. The numbers determine the order of the messages:

Figure 2.13. Object interaction diagram for doing laundry
  1. You ask the Launderer to do your laundry. You provide dirty clothes as a parameter.
  2. The Launderer hails a taxi and asks the Cabbie to go to the Laundromat.
  3. The Cabbie drives to the destination and lets you know when you’re there.
  4. The Launderer asks the Laundromat to clean the dirty clothes.
  5. The Laundromat returns clean clothes.
  6. The Launderer hails a taxi to get back.
  7. The Cabbie drives the Launderer back.
  8. The Launderer returns your cleans clothes to you.

Eventually, once you’ve worked out your class and object structures, you need to put them in Xcode. If you poked around the Hello World! project in chapter 1, then you’ve seen some files that were automatically generated, and by now, some of their names, like HWViewController.h, are starting to make a little more sense. You know enough to understand them better.

Organizing classes in headers and modules

In Xcode, each class has two parts: a header and a module. The header is like a table of contents. It contains a list of everything that objects of this class can do, but no details about how they do it. To use one of a class’s objects, you only need to know what’s in the header. If you poke around Xcode’s Project Navigator, you’ll find headers stored in .h files. The content of the header file is called the interface of the class.

The modules (which are put in .m files) are the actual details of how to do the tasks indicated in a message. The content of a module is called the implementation of the class.

Many times, in the implementation, you send messages to other objects. For example, in the Launderer class’s module, inside the “do my laundry” message, you’d find that it sends messages like “hail a taxicab” and “talk to the driver.” As you have seen, the messages for the driver would be in another class, and the cab’s messages would be in yet another. For example, the driver understands “take me to the laundromat,” and the car understands “go left,” “go right,” and “stop.”

One nice thing about all this is that it makes it possible for you to get some of your classes from other people. Maybe you’re working on a team, and you’re great at writing code for a car, and your teammate is great at writing cabbie code. They don’t need to know how the car does anything, and you don’t need to know the directions to the laundromat. You each work on the modules you understand, and the classes will work together just fine.

And the best part is that all the features of the phone are available for you to use this way. You send the Camera object a “take a picture” message and the GPS object a “Where am I?” message. You can concentrate on the parts that make your app unique.

Objects can be in a lot of relationships. But every relationship story has a beginning and an end. How do these objects meet? How do they break up? How are they born, and when do they die? These questions are some of the most important of object-oriented programming, and we’ll get to them in the next section. In the meantime, now might be a good time to strengthen your own relationships. Call an old friend, say hi, catch up.

Avoiding crashes by understanding object lifetime

In this chapter, so far, everything has been a guideline. If you don’t get it right, your app will probably still work. You don’t have to use MVC, and you can put all your code in one giant class. It will be hard to make improvements, but the iPhone doesn’t care about that. The same isn’t true for this section. If you don’t get object lifetime right, your app will eventually crash.

Before you can send a message to an object, the object needs to be created. If you never intend to send another message to it, it should be destroyed. This is because each object uses system memory while it’s alive. Your iPhone has a lot less memory than a desktop or laptop, so if the iPhone senses that you aren’t letting your objects die, it will kill your app. If you destroy an object and then another object sends it a message, the iPhone will kill your app because it’s talking to dead objects. There are other reasons why iPhone apps crash, but these are the most common. Luckily, with Automated Reference Counting (ARC), which we’ll always use in this book, you don’t have to do this yourself; but it’s good to understand what’s going on in case you run into problems, which is still possible.

The first thing to know is that Objective-C gives every object a count for you to use to keep track of how many objects are in a relationship with it. ARC is responsible for increasing this count whenever an object enters a relationship and decreasing it when the object relationship breaks up. The count is called the retain count. ARC increases it by sending a retain message and decreases it by sending a release message.

Creating an object is called allocating it (as in, “allocating memory for it”) and destroying it is called deallocating it. When an object is allocated, it’s assumed that the object will immediately enter into a relationship, so its retain count starts at one. When an object has a retain count of zero, it’s sent a deallocate message to free the memory associated with it.

As a result of the deallocate message being called, ARC knows that the objects it has are no longer being referenced, and it sends them a release message to indicate that the has-a relationship is about to end (because the containing object won’t exist). If no other object is using the object, its retain count becomes zero as well, causing a deallocate, and so on.

The object-lifetime diagram on the next page shows how the Launderer example might work. Objects start to exist after they’re allocated, and they live until they’re sent a release message that brings their retain count to zero. In this case, you have a simple, balanced allocate and release, remembering that the allocate created the object with a retain count of one. The final release causes a deallocate message to be sent to the object, which triggers releases to any objects it has. In this case, the release to Cabbie causes it to deallocate and release its Car (causing it to deallocate as well). The reason you never send a deallocate yourself is that you can never be sure that some other object isn’t also using it. The retain counting makes sure you don’t need to know if the object is still in use.

Figure 2.14. Object lifetime

Object lifetime is an important topic, and one that you need to understand well to make sure your apps don’t crash. ARC helps by sending all the release and retain messages for you; but you may still run into a crash now and then, so it’s a good idea to know what’s happening under the hood.

Applying object-oriented design

To understand object-oriented design, you’ll have to practice using it. You’ll get lots of chances to do this when you work with the sample apps in part 2 of this book.

But let’s try to put together the concepts using the laundry example. Imagine the object-oriented system inside the Laundromat. Until now, you’ve thought of it as a single object that you send the message “clean these clothes.” But in reality, it has a collection of classes that it needs in order to implement its messages. Here’s a partial class diagram to start with:

Figure 2.15. Laundromat classes

Fill in the following information:

  • Washing Machine and Dryer are Machines.
  • All Machines need to remember how much time is left.
  • Laundromat has one or more Washing Machines and one or more Dryers.
  • Washing Machine uses Detergent.
  • A Machine needs messages like “load clothes,” “put in money,” and “start.” Both Dryers and Washing Machines inherit these messages from Machine.
  • Washing Machine needs an additional message: “put in detergent.”
  • Dryer needs an additional message: “set heat level.”

When you’re done, the diagram should look something like this, but don’t worry if it’s not exact.

Figure 2.16. Laundromat classes complete

How did you do? Did you remember the three types of relationships you learned? Did you know where to put the messages? Did you understand how inheritance was represented? This is something we’re going to revisit, so you’ll have plenty of chances to see working examples.

Preparing to code object-oriented designs

You now have all the tools to start learning Objective-C. The diagrams you’ve seen are meant to help you organize your ideas enough that you can begin to code them. You’ll find that as you code, your diagrams will be wrong, and you’ll learn more about what you need to do as you do it. Maintaining the diagram to some extent will help, because looking at one diagram will help you understand things that can only be seen across many code files. Remember that each class consists of two files, and even very small apps may have half a dozen or more classes.

In the next chapter, you’ll see how each rectangle, circle, line, arrow, and other diagram element maps to code elements. You’ll see how to create the header and module files that describe a class, fill the class with messages, and handle the messages. Along the way, you’ll learn about conditionals, loops, variables, and the other things that are necessary to code the functionality of your apps.

Get Hello! iOS Development
add to cart
sitemap
×

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage