navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Objective-C Essential Training
John Hersey

Objective-C Essential Training

with Simon Allardice

 


In this course, Simon Allardice provides a nuts-and-bolts overview of Objective-C, the popular language for developing Mac, iPhone, and iPad applications, and discusses how to build a basic application using Objective-C and Xcode 4. The course shows how to download and install the development tools, covers every major feature of the language, and walks through the writing, compiling, and debugging stages of development. Programmers will also learn about memory management, a vital aspect of programming in Objective-C and the Foundation framework.

This course was updated on 08/01/2012.

Topics include:
  • Understanding the structure of an Objective-C program
  • Logging messages to the command line
  • Writing conditional code
  • Working with variables, classes, and functions
  • Creating code loops
  • Using existing classes in the Foundation framework
  • Managing memory usage
  • Introducing Automatic Reference Counting
  • Creating custom classes
  • Working with arrays
  • Reading and writing strings
  • Understanding inheritance and NSObject
  • Using Categories and Protocols
  • Compiling and debugging code

show more

author
Simon Allardice
subject
Developer, Mobile Apps, Desktop Apps, Programming Languages
software
Xcode 4, Objective-C
level
Beginner
duration
6h 35m
released
Mar 24, 2011
updated
Aug 01, 2012

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi, this is Simon Allardice and welcome to Objective-C Essential Training.
00:08Sure! There are dozens of languages you can choose from, but if you want to build
00:12applications that run on the Mac, you want to build applications that run on the
00:16iPhone or the iPad, there is one clear winner: Objective-C.
00:21It is the language of choice for building apps that run on Apple hardware.
00:25We will begin with the basics.
00:26Getting the tools that you need, the structure of an Objective-C program, how to
00:31get your first code up and running.
00:32We will explore what's available in the Foundation framework, a collection of
00:37prewritten code that's there in every Objective-C project you write.
00:41You will see how to design and create your own classes and there is a big
00:44section on memory management, a huge part of programming in Objective-C world.
00:49And at the same time, we will explore Xcode 4, the application you're going to
00:54use to write, test and debug your Objective-C programs.
00:57We will wrap up with some more advanced topics like dynamic typing.
01:01So, let's see how Objective-C works and the best way to work with it.
01:05Welcome to Objective-C Essential Training.
Collapse this transcript
What you should know
00:00In this course, I am starting with the idea that a) you know you are where on
00:04the Mac and b) you have some programming experience. That's it.
00:08You don't need to have done any Mac or iPhone programming.
00:12You might never have even seen Objective-C before.
00:15That's all fine, but I do expect that you can write code.
00:19To make the most of our time here, this course is not an introduction to programming.
00:24So I expect you're very familiar with programming fundamentals already. Loops,
00:28variables, conditions, functions, the core pieces and concepts of programming
00:33found in any language.
00:35Now, you might've heard that if you know a C-based object oriented language
00:39like C#, Java or C++ that you've got a head start with Objective-C.
00:45Well, technically yes, those languages are related. They all have curly braces,
00:50they are all object oriented, yada, yada, yada, but don't get cocky.
00:55If you think that all you need to do here is pick up a little syntax, you're
00:59going to hit a brick wall.
01:01In your first ten minutes with Objective- C, you'll see things that will not make
01:05sense and if you try and force them into a piece of knowledge that you know
01:10about C++ or a piece of knowledge that you know about Java, you'll find this
01:15journey very painful indeed.
01:17Objective-C is different, sometimes very different, and that difference is way
01:23more than just syntax.
01:25Over the years, Objective-C has developed its own customs, its own ways of doing
01:30things that are almost certainly unlike anything you've seen before.
01:34So whatever language that you know, leave most of it behind and just bring those
01:40core fundamentals to the table with you.
Collapse this transcript
Using the exercise files
00:00If you're a premium member of lynda.com or if you're watching this tutorial on
00:04the DVD-ROM, you have access to some exercise files used in this title.
00:08I have them here on my desktop in this folder and what you'll find is that some
00:13of the chapters have their own folder and inside of some of these folders there
00:17are files that represent the code that's written in the movies.
00:21And sometimes you'll find files that are just text files and this is just code
00:25you can copy and paste into your own projects.
00:29And other chapter folders might contain subfolders that might be the starting
00:34version of a project and the finished version of a project.
00:36If you find that the file that you're looking for is the one that ends in
00:40xcodeproj for Xcode project, you can just double-click that to open it in the
00:45Xcode coding environment.
00:47Now these are all just for convenience. If you don't have access to the exercise files,
00:51you can follow along from scratch or create your own assets.
00:55There's nothing major created as a starter file in this course.
Collapse this transcript
1. Getting Started
Installing the tools
00:00We are ready to get started writing some Objective-C. Now it is just text,
00:04so we could write Objective-C using text edit or even with the terminal prompt, but we're
00:08not going to because I don't want to put myself through that much pain and inconvenience.
00:12We're going to use Xcode, and we will get it from a Mac App Store. If it's not clear, yes,
00:17you are going to need a Mac. The development tools are not cross-platform here. It is technically
00:23possible to write Objective-C on Linux or Windows, but I'm assuming that you're watching
00:27this course because you want to build apps for iOS devices or for Mac Desktop and Laptops
00:33and you will need a Mac for that.
00:35You should be running a recent operating system, Mac OS 10.7 Lion, or OS 10.8 Mountain Lion.
00:43You can install Xcode on Snow Leopard OS 10.6, but you certainly don't want to be any earlier
00:49than that, and being on the latest operating system is highly recommended if you're going
00:54to developing on an Apple platform.
00:55So I'll be using Lion as my operating system right now for this movie, and I'll jump and
01:01open up the App Store. Once this is open I am going to find the category called Developer
01:07Tools, and that's where we'll find Xcode. Xcode is an IDE, or Integrated Development Environment.
01:14Like Visual Studio or Eclipse or NetBeans, and being an IDE just simply means it does
01:20more than one thing. It's not just a text editor. Yes, we do write our code using Xcode,
01:27but we will also use it to test and debug our applications, to organize our projects,
01:32even later on to build interfaces for iOS and Mac Desktop applications.
01:38On some other languages in other environments you might shop around and try a bunch of different
01:43IDEs and code editors, before figuring out which ones should suits you best, but really
01:47with Objective-C, Xcode is the one to use.
01:51In this course we will be using Xcode version 4, and I am recording updates to this course
01:56in June 2012, and right now the specific version is Xcode 4.3.3.
02:01Now if you use another programming environment or development tool, you might be used to
02:06a release cycle that's every one, two, or even three years between major updates. Now
02:11be aware that Apple release updates to Xcode often. Every few months there is typically
02:15a new version. Usually, it's just a point release, but because it's free, when Apple
02:20updates it, they just release the update straightaway.
02:23Now usually it's just some minor updates, some additions, but it can include cosmetic
02:28changes and make what you see a little different from what I'm recording. You don't need to
02:33have an identical version to mine. I suggest just always having the latest released version.
02:38Now this is a fairly large download if you look over here in the Information section,
02:43you can see it's 1.43 GB, and it's so big because it isn't just one program just Xcode,
02:49it's actually a whole suite of applications, documentation tools, and code libraries.
02:56Everything you need to develop Macintosh Desktop Applications, to develop iOS applications for the iPhone
03:02and iPad, all of that is bundled together into this one download.
03:07Now I already have it installed as I can see here, but if you haven't, go ahead and grab
03:11it, and after it's installed, you'll find it in your Applications folder. Now one thing
03:16to mention, before you go much further, you should become a familiar with the web site
03:20called developer.apple.com. This is the Apple Developer Center, and you get a lot of technical resources here.
03:28When you get here, you will find that it's split into three main sections. With Objective-C,
03:33we are usually interested in the first two, the iOS Dev Center targeted at developers
03:38working on iPhone and iPad and the Mac Dev Center for developers working on Mac Desktop
03:43or Laptop applications.
03:46You can join Apple's iOS developer program or their Mac developer program. In the US
03:51that's currently $99 a year. The biggest reason to join either of these programs is that when
03:57you make an app, and you want to put it in the App Store, either for iOS devices or for
04:02the Mac, you will need to be a member of one of these programs.
04:06Now for this course you don't need to be a member of either program, but you should register
04:10as an Apple Developer if you haven't done that already. Either in the iOS Dev Center
04:15or the Mac Dev Center, you'll find a link to register for free. Right now, it's up on
04:21the top right-hand side, you can register here as an Apple Developer, and this allows
04:25you access to a lot of technical resources.
04:28And we do it to get full access to the documentation found on Apple's developer site.
04:33We are going to get to that documentation through Xcode.
04:37So once you have installed Xcode, and you have registered as an Apple Developer, we will be ready to go.
04:45
Collapse this transcript
Creating your first application
00:00You're probably impatient to get going. So we are going to jump into
00:03Xcode, write a program, and then we are going to jump right back out again. Because if you're
00:07new to this, in just those few moments you are likely to see quite a few things that
00:12you will want explained.
00:13Now there is a tradition in programming that when you learn a new language, you write a
00:18Hello World program, a really simple program that just outputs those words, and it's kind
00:24of corny, so I can assure you that in this course we will never need to write the words
00:29Hello World. We are not going to write those words, because Apple is going to do it for us.
00:35So once it's installed, we'd launch Xcode. You will find it in your Applications folder,
00:40the normal location. I have just created a shortcut to it in my dock here, and we'll get the start window appearing.
00:47And the first option you get here is to Create a new Xcode project, and that's what we are
00:52going to click here. The new project window appears. This is not new file or new document
00:57or new program. Xcode organizes your content into projects.
01:02Right now just think project equals application. When I make an iPhone app, that's a project.
01:08You want make a Mac Desktop App, that's a project. You want to make a tiny simple app
01:13just to test a piece of code you thought this morning, that's a project. What that means
01:17for you is that when we make a new project, Xcode makes a folder on your hard drive and
01:21puts all the relevant files inside that folder.
01:24Xcode provides a variety of different project templates, preconfigured examples suggesting
01:30starting points. These help us make iPhone applications and Desktop applications and
01:35they will be very useful, but right now they will get in the way of us focusing on the language.
01:39So we are not going to start with an iPhone application from this iOS section.
01:44We are not going to work with any of these system plug-ins or application plug-ins.
01:49We're going to create an old-school command line application, the simplest kind of UNIX or
01:54DOS style command line app that runs from the console. No user interface, no buttons,
02:00no images, no text field. That's not important right now. So under the Mac OS X section,
02:05I am going to select the Application entry on the left-hand side here, and then with
02:10that I will select the Command Line tool option. Tool is just a word that Apple uses for an
02:17app without a user interface.
02:19So then click Next. Now there are three things on this next screen that we care about.
02:26Most simply, what is our product name, which means what do you want to call this program, this application?
02:31I am going to call this FirstApp. Now underneath that you'll have a Company
02:37Identifier, and depending on the version of Xcode you have, you may also have an Organization Identifier.
02:42Those aren't really important for our purposes here. You could write whatever
02:47you wanted here, and it wouldn't make a difference, but under this we have what's called a Type
02:52and this does make a difference. This dropdown box here has C, C++, Core Data, a few others.
02:58Now we know that we are not doing C or C++, this course is all about Objective-C, but
03:04Objective-C doesn't seem to be written here. Well, that's because in this course we will
03:07need the option called Foundation, and this would be our classic simple Objective-C program.
03:13We will talk about what the word Foundation means in a minute. In this course you will
03:18always choose Foundation for the type of project you're creating here.
03:23Under that we have the Use Automatic Reference Counting option, and as a developer you're
03:29almost always going to have that checked, because it will make your life significantly
03:33easier if you do, and we will talk about this particular check box a little later on.
03:38So we give it a name, we check that the type is Foundation, and not Core Foundation, but
03:43Foundation, and we have Use Automatic Reference Counting checked.
03:47Then click Next, and it asks. Where do you want to save this project? It could be pointing
03:53to the Desktop, it could be in your Documents folder. It really doesn't matter.
03:57You can choose wherever you want to do this. There is no magic location that you must save your
04:02Xcode files. I'm going to point it to my Documents folder, which is fine and under this we also
04:08have an option for Source Control, a check box. Do you want to create a local git repository
04:13for this project? I am going to make sure that, that is unchecked.
04:17This all about Source Control, managing revisions to our files and working with other people in teams.
04:22It can be very useful later on, but for the moment we don't need to bother about it.
04:28So I then click Create, and Xcode appears with our new project. Here is the super quick
04:33breakdown of what we're looking at here. The left-hand side over here is the navigator section.
04:39It will show me everything in and everything about the project, all the files,
04:45the settings, the configuration options. I see that my project that Xcode has created
04:49seems to have a bunch of different folders in them. I can expand some of these folders
04:53and by single-clicking, I can focus on one part of the project.
04:58If I single-click on a file here that can be edited what will happen is I'll see it
05:02open up in this middle section over here. And we'll spend a lot of time in this.
05:08This is the editor section. I got this view by single-clicking. If instead I had double-clicked
05:13that file that said main.m, what will happen is it will open in a separate window.
05:18I don't need that. So as a general rule, I am just going to single-click when I'm selecting
05:22my files in my project. The toolbar at the top of Xcode here will let me run this application,
05:29select how to run it. This center section here that currently says, Installing Xcode
05:34Developer Library kind of looks like a little LED screen and will in fact show messages
05:38about anything that Xcode is doing as we are working with our project. It's kind of like
05:42how iTunes displays messages when you're copying or syncing. You will see the same kind of thing here.
05:48Over on the top right section you should have two groups of three buttons, and right now
05:53in the first group what's called the Editor group we have the first one to press.
05:57This is what's called the Standard Editor, and we will see the others later. In the second section
06:02we have three buttons that can be toggled on or off. This first one has a highlighted
06:07left section. If I click it, we will actually see that navigator section come on or off
06:12and as you might guess, if I do it with the right-hand section, we will see that turn
06:16on or off as well.
06:18Now Xcode is not one of these programs where you can detach these panels and rearrange
06:23them as you see fit. The layout is the layout of Xcode. You can turn certain sections on
06:29or off, make them invisible, but you can't move them around. The navigator section for
06:34example will always be on the left-hand side. We also have this middle button here that
06:39can turn on a lower section which will give us debug and diagnostic information.
06:45I am just going to leave the Navigator section turned on right now. Now we are going to cycle
06:50back around into different parts of Xcode in a little while and start to dive into some
06:54of these other options and all the icons that we see here. But right now just think of these
06:58two main panes as on the left-hand side shows us everything in our project. And this section
07:05here, the Editor, shows us the one thing that we are working on, and in a very simple Command
07:10Line tool that we just created, we are really interested in one file, which is main.m here.
07:17.m is the suffix that means Objective-C, and we can actually ignore all the other files right now.
07:23So this is our program and all it does right now is output the message Hello World.
07:28And if I had to run this, I am going to go up to the toolbar section and find the button
07:32that says Run, and then click it.
07:34And we get a message that says Build Succeeded. Objective-C is a programming language that
07:40needs to be compiled before we run it, and build just means compile and link this program
07:45together so it can be run. Now the question is well, what did it do? And we can run it
07:50multiple times, and if I decide to do that, just by clicking the Run button again.
07:55If you're scanning down here at the bottom section, what we are seeing is this Output message.
07:59It might not be all that visible, but we are outputting the words Hello World!
08:04The section here at the bottom is called the debug area, and if you notice, the button up
08:08at the top has become depressed or toggled on because we need to see it just to see
08:14the output of this program.
08:16Because we have just made a command line tool, I don't have any kind of Window or iPhone
08:21application up here. I just get a message. Now to make some of this more visible, I am
08:25going to make a couple of changes right now to the Xcode Preferences. You don't have to
08:30do this, but you'll see why I'm going to.
08:32So up in the Xcode menu I am going to come down into Preferences, and I am going to do two things.
08:37First in the Fonts & Color section I'm going to select the theme called Presentation.
08:43What that's going to do is make our code and our Output messages a bit more visible and
08:49then in the Text Editing section of this preferences, I am going to check the box that says Line
08:55numbers, which will give us line numbers in this gutter section over here just so I can
08:59talk about the lines as we are going through them.
09:02So back to the code, if you were to scan it, it's not difficult to spot the one line that's
09:07responsible for that Hello World! message. Line 17 here says NSLog@"Hello, World!".
09:16NSLog is the equivalent of printF in C or system.out.printline in Java or console.rightline in C#.
09:25It's just a way of getting a message out of your program and onto the console.
09:30But we have got a few other things going on here. We have got this import line up on line 9.
09:35We have got the line that says main on line 11 and particularly the rather cryptic @autoreleasepool
09:44on line 14, and we're going to get into all of this, but even from just scanning it, we
09:48can see that we get color coding of the different pieces of syntax showing the difference between
09:53say comments on line 16 and keywords and variables.
09:58Now this is not unusual. Most IDEs give us the same thing. As you might imagine, like
10:03most IDEs, if we click in here and start typing, we will get automatic indentation.
10:09We will also get code sense, which is Xcode auto-completion feature. If I start typing, for example, I
10:14type in the letters NSR, we are going to get this pop-up, and as I type more things, it
10:20might start to filter down and give us even fewer options.
10:25If I see many options, I can use my cursor key move up and down to select the thing that
10:29I'm interested in and just hit Return to select something. This helps us a lot, particular
10:34because you find that Objective-C in general has a lot of very long names for its functions and methods.
10:39Now I don't actually need to use this piece of code at the moment, I'm
10:43going to delete it in just a second. But you will notice, already that I have this exclamation
10:48mark appearing in the gutter section over here for line 18. That's because Xcode 4 tries
10:54to highlight issues with the code as you're typing it, and it's often pretty quick about
10:59it, and you haven't even finished a line before it starts complaining about it, but you will see this a lot.
11:04So I will just delete that line because we don't need it. Now as you might expect, Xcode
11:09does have a lot of other options. It has ways to do test driven development and source control
11:13and refactoring. There are Code Snippets, ways to build interfaces and help you manage
11:18your projects. But what we have seen so far will be enough to help us get going, because
11:22some of these options really aren't worth bothering with, until we have got a bit more code.
11:27
Collapse this transcript
Updates to this course
00:00I originally recorded this Objective-C Essential Training course in March
00:032011, right when Xcode 4.0 was released. Now since then Apple have made a few point releases
00:10to Xcode, usually to coincide with a new Mac or iOS operating system.
00:15Those changes aren't big enough to require an entirely new course, but right now mid
00:202012, I'm recording a few updates and additions to the course to include these new features.
00:26What that means is you will see me using two versions of Xcode during this course.
00:30Xcode 4.0 from the original recording and Xcode 4.3 when I want to point out a new feature
00:36or a significant change.
00:37Now for the most part everything is exactly the same because we're really focused here
00:42on the essentials of the Objective-C language rather than on Xcode itself, but there is
00:47one main difference you're likely to see.
00:49In some movies from this point on, you'll see me working with projects created in Xcode
00:534.0, and there will be some automatically generated code, it looks like this, using the word NSAutoreleasePool.
01:01Now, however, if I created that same project in a more recent version of Xcode like 4.3
01:07as I did a moment ago you'll see generated code that looks like this, using the @autoreleasepool keyword instead.
01:13Now in fact, there are actually two lines that are different here. In Xcode 4.0, we
01:18have that NSAutoreleasePool, and we also have the words pool drain in square brackets right
01:24before the line that says return.
01:27In later versions of Xcode you would see the @autoreleasepool keyword with an opening brace.
01:34And instead of the words pool drain, you would see the closing brace right before the word return.
01:40The new way is a little simpler to read, a bit more concise. Don't worry too much
01:45about what exactly these lines mean, just realize that you will see both ways in this course.
01:50There are a few reasons why I didn't want to rerecord every movie with a new way and
01:54pretend the old way never existed. Well reason number one is that these lines are
02:00not the lines we care about. This code is generated. We don't write it, and we don't
02:05need to touch it. Everything that you're going to be doing is here. Xcode even tells us where
02:10to put our own code, and that's whether that's using the old versions like I'm seeing here
02:15or the new versions, the code we're interested in is exactly the same, and more importantly
02:21the older way still works and it was used for years.
02:24So, if you're going to continue with Objective-C, you'll be reading code on websites and in
02:28books, and you're going to see it the new way and the old way, so you might as well get
02:32familiar with seeing it. But the main change that Apple made, since I originally recorded
02:38this course, is with a feature called ARC or Automatic Reference Counting, first made available with Xcode 4.2.
02:47ARC is a good thing. It's a great addition that makes working with Objective-C much easier
02:52than it used to be, particularly for people new to the language. I'm going to cover Automatic
02:57Reference Counting later in the course when it's most relevant, and there will also be
03:01a couple of places where I'll point out another new feature or best practice.
03:05As I have mentioned, and, as you can see, from this timeline, Xcode changes quite frequently,
03:10and part of being an Apple Developer is keeping abreast of those changes made to it and to
03:15the various parts of the Apple developer world, and that might sometimes sound like a pain,
03:19but note that Apple don't tend to add new features just for the sake of it.
03:23When Apple change things they usually get easier. And that's definitely been the case since the
03:27course was first recorded as we'll see shortly.
03:37
Collapse this transcript
2. Objective-C Basics
The Objective-C language
00:00So why Objective-C anyway?
00:02Why not something more widespread like Java or something more modern and
00:05fashionable like Ruby or Python?
00:07Well it's as much history as anything else.
00:10Go back 40 years we get the C programming language, enormously popular and
00:16influential. A lot of languages today owe their existence or at least
00:19their appearance on C.
00:21But fast-forward a few years into the early 80s you had Smalltalk, the first real
00:26object oriented language and people thought an object-oriented version of C
00:30would be a great idea.
00:31Now some ways of doing this were creating languages like C++ and
00:36spawning off a new language with these ideas, and other ways such as in
00:40Objective-C we took some ideas from Smalltalk and baked it into C, and that's
00:45an important distinction.
00:47There are languages like C++, Java, and C#, which are all C-based object oriented
00:53languages, but they were all designed from the ground up as their own
00:57independent language.
00:58They have their own identity, they have their own rules, their own lifetime, but
01:03Objective-C was not designed from the ground up as a new language.
01:08It is simply the C programming languages with stuff added to it, packed on top of it.
01:14It's what's often referred to as a strict superset of C. I could copy and paste
01:19a bunch of C from the 1970s into Xcode today and expect it to compile.
01:24I couldn't do that with Java or C#.
01:26Now why is that important?
01:29Well, if you are going to have a new language that's combined with an older
01:32one, how do you indicate which parts are old school C and which parts are the
01:36new Objective-C parts?
01:38If you're a C programmer, you could read some code like this and it would strike
01:42you as very strange.
01:43Some of it would look very natural; other parts wouldn't.
01:46That's because we're going to give the compiler some clues by marking these pieces.
01:50You'll see a lot of square brackets used in Objective-C, because these are added
01:55Objective-C ways of doing things.
01:58You'll see a lot of @ signs in Objective-C, because we're indicating
02:02the compiler that this isn't just regular C; this is the new stuff. This is Objective-C.
02:07You'll see the letters NS being used in front of a lot of terms in Objective-C.
02:12There are other words we'll run into. @interface, @implementation, @property,
02:17@synthesize, all telling the compiler we want to do things that aren't
02:21allowed in regular C.
02:23And those two letters NS will permeate everything we do in
02:27Objective-C development.
02:29Okay, but that doesn't explain why we use it now.
02:31Well in the 80s Objective-C was adopted as the main language of the company NeXT
02:36Computer, which Steve Jobs founded after he left Apple in 85.
02:40And they built everything including their NeXTSTEP operating system on Objective-C.
02:45That was first released in 89, and in 96 Apple bought NeXT and they roll over to
02:50the NeXTSTEP operating system into what would become Mac OS X in 2001.
02:55And that's why we have this history, and we use that NS term all the time,
03:00because NS comes from NeXTSTEP.
03:02The last version of NeXTSTEP, which was out in 95. So Mac OS X is built on Objective-C.
03:08The iPhone which came out in 2007, it's operating system is built on Mac OS X.
03:13In 2007 too, we had a new version of the language, Objective-C 2.0, that had some
03:18more modern features.
03:20As we go forward we've got the current OS that I'm using in this course,
03:23Snow Leopard 10.6 released in 2009.
03:26We have the iPad released in 2010, also built on this history.
03:31And in 2011 right now Xcode 4, the iPad 2, and OS 10.7, Lion, which will be
03:37out during the summer.
03:38You see, Objective-C is not some arbitrary choice. It's a historical necessity.
03:43Mac OS X is built on over 20 years of layers of Objective-C history and the
03:49iPhone OS or iOS is built on top of that.
03:52You can't pull Objective-C from this picture. It's woven through it at every level.
03:57So yes, although the @ signs and the square brackets can look a little strange
04:01when you're coming from a pure C-based language, hopefully now you know there is
04:06a reason that they look that way and there is a reason that this is what we're
04:09going to forward with.
Collapse this transcript
The structure of an Objective-C program
00:00Let's take a look at the structure of a basic Objective-C program.
00:04Opening up Xcode I'm going to make a new project. I could also do this from the File menu.
00:09And again the best choice for just concentrating on the language is to make a
00:13command line tool. Selecting Application under Mac OS X, not under iOS, and Command Line Tool.
00:20And then one you want is a Yype of Foundation, not Core Foundation.
00:23And just give it a name. I'll choose Structure. Click Next and choose a place
00:28to save it. I'll choose my Documents folder and I'm leaving the Source Control box unchecked.
00:33It jumps us into the rather intimidating looking settings screen, but I can
00:38ignore this. I don't need to touch this right now.
00:40What I'm interested over here on the left-hand side in the project navigator is
00:45the file called main.m. Our Objective- C is stored in files that end in .m and
00:50we've got only got one in this project.
00:52Let's take it line by line.
00:53Well, the first section all in green are just comments. Objective-C being C
00:58has C style comments. They begin with two forward slashes and then you just
01:02write whatever you want.
01:03The first important line is this one that says #import. This is pointing to the
01:10Foundation framework header file.
01:12Now what does that mean?
01:14It simply means we're telling the compiler that the code I'm about to write can
01:18use the Foundation framework and anything inside of it.
01:21What that gives us is a little over a hundred really useful files for working with
01:27strings, and dates, and arrays, and other types of collections. That will come in
01:32very handy later on.
01:34Officially, it's not part of the language.
01:36It's little add-on, but it's an add-on we're going to use in every single
01:41project we write, whether it's command line, desktop, or iPhone.
01:44If you're coming from a C background, the #import is like #include except this is
01:50a little more error proof.
01:52The next line on line 11 that begins int main is the most important.
01:56As in C, Java, C#, C++, to run an Objective-C program that could be thousands
02:02of lines across dozens or hundreds of files of Objective-C, well it needs to
02:06know where to start.
02:08And Objective-C expects that somewhere in your code there is one block of code
02:13called main and this is it.
02:15If you're new to C-based languages, there might seem to be a lot going on here
02:19after the parentheses, but most of it we can pretty much ignore right now.
02:23We're moving on. The braces on line 12.
02:27These can puzzle people who are new to C-based languages and they really
02:30shouldn't. They have no meaning. They just say where something begins and where it ends.
02:35They just surround a block of code. They're often referred to a statement blocks.
02:39If you have an opening one, you must have a closing one. They must pair up.
02:44In fact by mousing over to this section called the gutter on the left-hand side,
02:49Xcode will actually highlight where this one opens and where it closes.
02:53Sure, it's pretty obvious right now, but later when you have large amounts of
02:56nested code this can be quite useful.
02:59So main begins where the curly braces open.
03:02It finishes where the curly braces end and all the code we're going to
03:06execute is between the two.
03:08Do have a notice that main is written in lowercase. Objective-C is case sensitive.
03:13Let me say that again. Objective-C is case sensitive! And if you are coming from
03:18a case insensitive language you may want to remind yourself of that on a
03:22regular basis, or you will be reminded regularly with a string of cryptic error
03:27messages,that you'll spend much of your life trying to figure out before you
03:30realize you had a lowercase S where you should have had an uppercase S or vice versa.
03:34Now you shouldn't ever actually need to write main yourself. It will be there
03:38for you in any project you make an Xcode, even when you write iPhone, iPad,
03:42desktop applications. Your app will start by looking for a block of code called
03:47main that kicks everything off and if it doesn't find it, it will crash.
03:51So, moving into the block of main, the first line of code that actually does
03:55something as this one that begins with NSAutoreleasePool.
03:59This has to do with memory management and we'll explore this quite a bit later on
04:03for now we can just let it pass, including the square brackets and what they do.
04:07We hit another comment, and then we have our output message.
04:11Again NSLog is the equivalent of printf or system.out.print line in Java or
04:16console.write line in C#.
04:17Now Objective-C is a whitespace insensitive language.
04:22What that means is if we want to split lines of code onto multiple lines, we can
04:27do that without worrying about it.
04:29If I had a longer line like this one at the top, I could just hit Return and
04:33spread it to two lines if I thought that I made it more readable.
04:36Now obviously, you can put spaces in the middle of words. You can put space in
04:41the middle of operators.
04:42In fact, the only place it's kind of sensitive about them is within a string
04:47within a block of text surrounded by double quotes, just because there is a
04:50difference between the words Hello World and Hello, space space space, World.
04:55The rest of the time it doesn't care.
04:58So we output the message and then we move on. Again with the square brackets
05:02around pool and drain. We'll come back to both memory management and square
05:07brackets, which is what we're dealing with here.
05:09And then finally, on line 21, return 0.
05:13This is the last line of main and it's effectively saying main was successful.
05:18We end with the closing curly brace. Our code is done, our program is finished.
05:23But even in this simple code, we're seeing these letters NS pop up allover the place.
05:29Now these NS lines are actually part on this Foundation framework.
05:33Technically, they're not part of the Objective-C language. They're extra pieces
05:38that we're linking to.
05:39But they're extra pieces that because we link to the Foundation framework
05:43we will have available in every single line of code that we write. But this is the
05:48entire structure of a basic Objective-C program.
05:51But surely what about when it gets more complex?
05:53Well, we could type 5000 lines of code in-between the opening and closing
05:58curly braces of main, but more likely we'll split up our project into multiple code files.
06:05However, we will always begin in main and from main, we'll call into other parts
06:11of our project, but we'll see that later on.
Collapse this transcript
Compiling and running your code
00:00Objective-C is a language that must be compiled before you run it.
00:04Here are a couple of things you should know about this and a couple tips and
00:07tricks to make your life a little easier.
00:09Now, the term we used to tackle our Objective-C in a project, compile it, link
00:14everything together with any frameworks you're using, and end up with something
00:18you can run on actual executable program, and the term we use is Build.
00:23When you run your program just by clicking the Run button, if I hover over this,
00:27I will see that really what's happening is Build and then run.
00:31We can also go to the Product menu and just say Build.
00:35It gives me a Build Succeeded or I can use Command+B as the shortcut to build this.
00:41Xcode doesn't actually do the compilation itself.
00:44It uses something in the background called the LLVM Compiler to do it and feeds
00:49it all your Objective-C, but it manages that process.
00:52If our only feedback here is Build Succeeded, well it goes away and maybe I
00:57want a bit more information. Well, I can get that.
01:00If I come over to the Navigator on the left hand side, and you have probably
01:05seen there is a lot of little icons along the top. There's seven of them.
01:08We can click this one that looks like a speech bubble on the far right-hand side
01:12of the Navigator and this is the Log Navigator.
01:15These are the log messages from our project and they show all the builds and
01:19runs of this project, the most recent is at the top.
01:22If I select this one, it says the build succeeded. There were no issues.
01:26Although this Navigator does have seven different icons and feel free to explore them,
01:32early on your most important parts of the Navigator will be the first
01:36button that shows the files in our project and this last button that shows the log messages.
01:41After that, you'll probably find that the most important one will be this middle one,
01:46the exclamation mark. It represents issues with your project.
01:50And the big issue of course is what happens when you make a mistake with your code?
01:55And notice that I say when you make a mistake, not if you make a mistake.
02:00Well, let's go back and run this again.
02:03Before I do, I'm going to make a mistake here and remove the closing double
02:07quote and then click the Run button.
02:11It says Build Failed and highlights the line here.
02:14Our program does not run because there are build errors.
02:19That highlights the line, but depending on if I have a lot of code, that line
02:23might be somewhere else off screen or in another file and I might not see it.
02:27Well, the top window also tells me that there were issues here and if I
02:32come over to the exclamation mark, I can actually see what's called the
02:36Issue Navigator that says there were problems here. A missing terminating closing quote.
02:42So, there are issues. A variety of different ways to see them.
02:46Now, sometimes but not always, Xcode will make a guess as to what the problem is
02:53and it's often worth clicking the icon that you'll see in the gutter here as it
02:57might suggest a fix.
02:59This is called the fix- it functionality of Xcode.
03:01You won't always have a suggestion.
03:03Sometimes Xcode has no idea what you're trying to do there.
03:07So, I'm going to fix that just by adding that double quote back in and then
03:12I will notice even before I actually do an official build that that icon goes away.
03:18In Xcode 4, you don't even need to wait until you do a full build.
03:22This fix-it functionality will check your code as you type, showing you any
03:25issues it's coming up with.
03:27Sometimes that can get a little annoying because if you're typing slowly for
03:31example, it might flag a line before you've even had the chance to finish it, as
03:36it's just on here. But I'm going to add something and finish this one off.
03:40And what it's doing now is instead of the red exclamation mark, I get a yellow
03:44exclamation mark, which is a warning.
03:47Technically, this is not as bad an error.
03:49If I click the Run button, it will go ahead and run the application.
03:53I even get my Hello, World message coming out there.
03:55I will just make that debug area go away, but I still have a warning that's
04:00showing up on this line here.
04:02It's showing up at the top with the exclamation mark and it's showing over here
04:06in the Issue Navigator.
04:08Again, I can also see it in the Log Mavigator for the most recent build where
04:13the build succeeded but there was one warning.
04:16Clicking that in the Issue Navigator, we jump to that line and the warning is
04:21in this case that this variable was unused.
04:24I've created something called X. I didn't use it.
04:27But let me be plain. Even though this is a warning, you should never ignore a warning.
04:32I lose count of developers, particularly new ones, who think that the only thing
04:36worth paying attention to are errors and the warnings are somehow optional.
04:40It really is detected that even though this code might be correct in syntax,
04:45something weird is going on and I have probably made a logical mistake.
04:48So, never ignore a warning, particularly in simple code like we are going to do in this course.
04:53You should have no issues at all.
04:55If you're following along and you have a warning and I don't, there's a problem
04:59with your code that needs to be fixed.
05:01Now, what you might find useful is a preference change or at least something
05:05worth taking a look at.
05:06I am going to open up the preferences of Xcode and the second section along the
05:12top is something called Behaviors and this drives what happens in Xcode under
05:17these events, such as when a build starts, when a build fails, when a build
05:21succeeds, when a build generates new issue, which is a very useful one. We can check.
05:27Well, when it generates a new issue, should I show the Navigator? Yes. Which part?
05:33Well, let's go to the Issue Navigator that's the default.
05:35That's a useful one.
05:36You could even make it play a sound or even speak an announcement using one of
05:40the built-in voices.
05:41If you select this, every time Xcode detects a new issue
05:46it will make this announcement. Build has generated issues.
05:49Now, bear in mind, I am selecting this for Build generates new issue, so if you
05:54get a warning, it will tell you the first time and if you then continue to
05:58compile, it won't speak a message because it will not be considered a new issue.
06:03It's presuming you just want to ignore it.
06:05Not a good idea but you could.
06:07So, there are two more things that I am going to talk about.
06:09Now, these last two are not really drastically important right now but you
06:13might have seen them and you might be wondering about them.
06:17First off, at the top of the toolbar is this dropdown box. This is what's known
06:22as the scheme and it affects how your project is built and run.
06:25In this case, it's giving us the option for compiling 64-bit versus compiling 32-bit.
06:32If I was creating an iOS project for an iPhone or iPad, this dropdown would
06:36give me the option of running on a simulator or running on a device that I
06:41might have plugged into my machine.
06:43So, by using schemes, Xcode supports multiple ways to build and run your application.
06:50Now one last thing on compiling.
06:52That screen you first saw when you first created a project.
06:55Now, to get back to it, I am going to go to the file section of my Navigator,
06:59what's called the Project Navigator.
07:01Highlight the project icon itself and we get this screen here with a lot of
07:05different settings on it.
07:06A lot of these settings are to do with compiling and building our application
07:11and most of it is fairly specialized technical options that you can safely
07:15ignore, although there are a couple of things that you will be able to do later on here.
07:21One is what's known as the Base SDK, which is what am I compiling this against.
07:27In fact if I take a look at the Build settings, I see that I have got a Base SDK
07:32that says what version of the Macintosh OS am I compiling against.
07:37I am on Snow leopard, so I am seeing 10.6, the latest version and you typically
07:43want to build with the latest version of the SDK that you have as a developer.
07:47But what you'll find is you also have something called a Deployment Target and
07:53that's what OS do I need my users to have, because you might have an
07:57up-to-the-minute system but want to allow your users to go back to say 10.4 of
08:02Mac OS or 4.0 of IOS if you're building an iPhone project.
08:07That can be done here too and in fact because these are some of the most
08:12common things you'll select, you'll often find them being targeted here on the
08:16Info section, which is kind of a cut-down version of all the different settings that you can pick.
08:21Now, in this course, we are going to be using the default scheme pretty much all
08:25the time and I am not going to be worrying about different deployment targets,
08:30because all the code we are going to write will be as general as possible to
08:35really learn the language.
Collapse this transcript
3. Program Flow
Logging messages to the command line
00:00I get it. You're bored with Hello, World, I'm bored with Hello, World.
00:04So, let's get into this language, variables and operations that will take us
00:08into loops and conditions and data types and scope.
00:12Over the next few movies, we will cover the core language constructs of
00:16Objective-C, much of which of course is based on C. So, if you have spent
00:22the last five years living in C and C++, you're likely to find some of this remedial.
00:27Yes, I agree, you know this already.
00:30Objective-C did not try to invent its own way to do an If statement.
00:34The one in C was perfectly fine.
00:36So, you can jump ahead or I invite you to sit back can sing along. We all need
00:41a recap form time to time.
00:43Now, if you are coming from something that's more C influenced like JavaScript
00:47or Action Script, well, then I suggest you go through all of it because even
00:52though there are significant similarities, it's the little differences that you
00:55need to focus on now.
00:57The things you take for granted but aren't true in this language. So let's get to it.
01:02So, we're still in the main function here and of course we are going to start
01:05simple and if you wonder where to put your code, well, Xcode of course does tell
01:09you to insert code here.
01:11Let me type a few lines and then I'm going to go through it.
01:17So, we have our first variables, our first calculation and our first slightly
01:21interesting output message, but still probably raising a few questions if you're
01:26new to this language, like what's the @ sign is for and what does the %i mean.
01:31So, let's take this one by one.
01:34Variables in Objective-C are declared as in other C based languages: first the
01:39type and then the name and then a semi-colon.
01:43Optionally, you can give it a value at the same time that you declare the variable.
01:47In Objective-C, we give our variables a type.
01:51If you are coming from a language where the same variable can first be an
01:54integer and then a floating point number and then a string or a button or a
01:58block of HTML, it's not the case here.
02:01You pick your type when you define the variable.
02:04Now, way down the line, there is something in Objective-C called Dynamic Typing
02:08but that's for much more complex situations and it's not what we do here.
02:12So, we begin here by declaring three variables, one for minutes equal to 60, one for
02:17hours, 24 and one for days, 365.
02:20These are integer variables, whole numbers with nothing after the decimal point.
02:25We do have other data types for floating point characters, Booleans, that kind
02:29of thing but we will get to those later.
02:32As in just about any programming language I can think of except maybe COBOL,
02:36we multiply with an asterisk.
02:39So, I'm creating the value of the fourth variable, minutes in a year, by
02:44multiplying minutes asterisk hours asterisk days and then on this line 23,
02:50I spit the value out that there are so many minutes in a year.
02:54So, let's run it and test it.
02:56Build Succeeded and apparently there are 525,600 minutes in a year.
03:02So, let's break down that NSLog message because that might look a little odd to
03:07you as well depending on what language you are coming from.
03:10Two things going on here.
03:14In Objective-C, strings are represented not just as some value in between double
03:19quotes but double quotes with an @ sign at the front of them and this @ sign is yet
03:23another indicator to the compiler that this isn't regular C and it harkens back
03:28to the days when C didn't really have strings.
03:31It just had null-terminated character arrays.
03:33It's something that trips up most programmers coming to Objective-C. At some
03:37point you're going to forget the @ before the double quotes and you'll get an error.
03:42That's it. It's not complicated.
03:44It's just something to remember.
03:46When you're thinking about a string literal idea like this, it needs an @ sign
03:50before the opening double quote.
03:50But we are doing something else with that string. We are trying to output a
03:55message that contains a calculated value.
03:58In other languages, you might create a message by combining or
04:01concatenating different pieces.
04:03Something like this. A string with There are and then a variable minutes and
04:07then another string with in a year; you might use plus signs of ampersands.
04:11But that's not what we do here in Objective-C.
04:14Instead we create our message and we put a placeholder in the middle of it.
04:20It's within the string itself.
04:22In this case, it's this %i. Now, placeholders always begin with a percent sign
04:28and then we are telling Objective-C what kind of data is going to go here.
04:32Since it's an integer, so we follow the percent with an i.
04:36And now knows there's going to be an integer in this message, but which one?
04:40We follow the string with a coma and then the variable that we want to replace
04:45the placeholder with.
04:47Now, if we had multiple placeholders, it expects multiple variables. So if I had
04:52two placeholders in my message, there are so many minutes in a so many a day year,
04:58I'd have two placeholders here and I'd follow this string with ,minutes,days,
05:05the two variables that I would want to replace those positions.
05:09They just go in order. The first variable after the comma would replace the
05:13first placeholder with the %i because it's an integer and the second one would
05:18replace the second %i.
05:19Now, as just as there are different types of variables, there are different
05:23placeholder indicators.
05:25We have %i for an integer, there %f for a floating-point variable, %c for single characters.
05:32We will see these and more later, but just for now, just remember that all our
05:36placeholders begin with the percent sign.
05:40And understanding the use of these what are called format specifiers in a format
05:45string will let us output more useful messages to the console, because we are
05:50always interested in manipulating output.
05:54Even when you start to move away from console apps to writing desktop apps and
05:59iPhone apps, you will still be using NSLog time and time again to write your own
06:04messages when developing and testing.
Collapse this transcript
Writing conditional code
00:00Let's talk about conditional code and if statements.
00:03Now if you have made it through any programming language without knowing the
00:07word if, I'd be very surprised.
00:09This is the classic if statement. How do you make a decision about whether to do
00:13one thing or another?
00:14Well in Objective-C is written as in other C-based languages with this format.
00:21We use the word if, we open parentheses that contains our condition, and then
00:27between the opening and closing curly brace, we write our code. We do whatever
00:32is between the braces.
00:33Now, whatever is inside the parentheses, the condition itself must evaluate as true or false.
00:40So if a is less than 5, if b is greater than 20.
00:44We are not really caring by how much b is greater than 20 but this has to be true or false.
00:52We can check equality.
00:54We can say have we got a variable called C and is it equal to the number 99.
00:59If you want to check equality in Objective-C like other C-based languages,
01:03it's the double equal sign and no spaces in between them.
01:07A single equal sign after all is an assignment operation.
01:12A single equal sign would set a value, not check a value.
01:16And you will get a warning in Xcode 4 if it detects you may be doing this.
01:21In this simple Command Line application, I'll just create a new variable called
01:25C and set it equal to the value of 100 using the single equal sign,
01:30the assignment operator to set the value.
01:33Xcode is complaining that C is being unused.
01:36That's okay. I haven't finished my code yet. So I am going to write an if
01:39statement to which we can imagine as little later on.
01:42Opening the parentheses, I am going to ask is C=100.
01:45I am going to make a mistake of only using one equal sign.
01:49Close my parentheses, I am going to open the curly brace, hit Return, and it
01:55will automatically enter the closing curly brace, which is nice.
01:58It helps me do that.
01:59But you can see it's already kind of complaining about something. It is detecting
02:03there is something weird going on.
02:05If I click over here to the gutter, it says I'm using the result of an
02:10assignment as a condition without parentheses.
02:12Wonderful little phrase there, but it's suggesting, do you want to turn this
02:16assignment into an equality comparison?
02:19Yeah, that will be a good idea. So a nice little reminder here.
02:22So I am just going to double-click and it will say now we would be checking if
02:25C is equal to that value. We could do a simple NSLog message, making sure to get the @ sign.
02:32Yes it is. Save that, run it.
02:36Not a particularly dramatic application but the build has succeeded and we can
02:40see yes it is, we are hitting that code.
02:43There is particularly something to pay attention to if you're not coming from a
02:47C-based language, that double equal sign for checking equality.
02:51What if we are more interested in a variable not being equal to something?
02:56Well, this is the format that we usually use. We use the exclamation mark equals sign
03:00to say in this case, if the variable d is not equal to 100 then we are going to
03:05execute the code inside the braces.
03:07Now, quick word about curly braces here.
03:10You're likely to see braces being used in a couple of different styles.
03:14They always mean the same thing. They surround a block of code, whether that's
03:18one line or a dozen or hundred, but as an example with the main method here,
03:23I can see that I have the opening curly brace on its own line and it closes on its
03:29own line and they're in the same position that they match up and again if we
03:32hover here, we can see this statement block being highlighted by Xcode.
03:38But you'll also see it this way.
03:39If I come down a little bit and move over, we can see that the if statement
03:44block begins and ends here but we've got the opening curly brace on the same
03:49line as the if statement and then not exactly aligning up.
03:53This is also a very common way to see the opening and closing curly braces,
03:57very common for classic C and C++ programmers.
04:01Now, people get religious about brace styles. Objective-C of course doesn't care.
04:06These are regarded as insignificant white space.
04:09If I put this curly brace on its own line, it would be fine with it there.
04:13It can also be opening right after the if statement.
04:17Technically, if after your if statement, you just want to execute one line
04:22of code such as this case, I actually don't need to have the opening and
04:26closing curly braces.
04:28That would actually work just fine. But I always use opening and closing curly
04:34braces after an if statement.
04:36I believe that it makes the code more readable and it makes it less prone to
04:40errors in case you come along and add some lines later. So I am always going to use the braces.
04:46What happens if I want to check multiple conditions to be true?
04:49I can do that as well.
04:50Let's say we've got a couple of different variables and I want to check
04:55the values of them.
04:57So in my if statement, I want my condition to be if c=100 and d>50.
05:04Well, the way that I do an And or a logical And operator is two ampersands,
05:10so if C is equal to 100, && d>50.
05:16That's very common of course to also take these and surround them with
05:21parentheses, just to make it a bit more obvious that these really are their own
05:26pieces, their own kind of sub-conditions in there.
05:29But again, the whole thing, the whole condition must evaluate as true.
05:35So if C=100 and d>50, then we should be writing out that error message, Yes it is.
05:43If I wanted to do an or operation, that's the two vertical bar or pipe symbol.
05:50On a US keyboard, it's the Shift+\ above the Return key.
05:56So in this case the whole condition that evaluates is true would be if C==100 or d>50.
06:03We would then write out the message.
06:05But what happens if that's not the case?
06:08Well after our if statement, we can follow it with an else statement, which has
06:12its own statement block.
06:14Of course, the else doesn't need parentheses because we are not checking a
06:17condition. We are just saying if it's anything other than the condition that was
06:21true, we are going to do something else, so it's otherwise.
06:25And we can even decide to nest if statements inside that, so I could have
06:30another if statement nested inside my else, but of course, if statements
06:34themselves will need conditions for all of them.
06:37You can of course do this. Don't nest to deep. Objective-C can handle it quite
06:41fine, but lots of nested if statements, say beyond two or three levels, can be
06:45quite difficult to read and to make sense of.
06:47So if we do have to have more complex logic, we will break things apart into
06:52their own functions.
06:53And as we'll see, if we are checking the same kind of variables, there are some
06:57different ways to write conditional code that may make more sense.
Collapse this transcript
The switch statement
00:00It's very common to realize that a lot of your if statements are checking the
00:04same variable or the same conditions, just multiple values.
00:09In this case, for example, we have got an integer called category = 47 and then
00:14I have got an if statement that checks is it equal to 40. And if isn't, well
00:18then is it equal to 41?
00:20And if it isn't, well, then is it equal to 42?
00:23And it's very easy to create fairly convoluted and dull-looking if statements
00:29that are really just checking the same thing.
00:31So, there is another way, using the switch statement.
00:34I am going to delete all that if statement nested garbage and replace it with
00:40something called switch.
00:42Now, when we do a switch, we are always checking or testing the same thing again and again.
00:48So, I use the switch and I say what are we switching on?
00:52What expression are we checking?
00:53I am going to say in this case, the category.
00:58And a switch block kind of looks a little bit like an if statement here but
01:02instead of if, parenthesis, open curly brace, close brace, we just use the word switch.
01:09Within the block, we then have to say what are the possible values that I'm interested in.
01:14And the way that we do that is by using the keyword case.
01:19So, in the case that category is 40, I want to do one thing.
01:24In the case that category is 41, I will do something else.
01:27Now, when we use this case statement, we end it with a colon.
01:31Not a semi-colon, but a colon.
01:34It's one of the few cases that we would do this.
01:36So, I could write in multiple cases, case 41, case 42, case 43, and so on.
01:44Now, I am going to go back and fill these out a little bit but it makes it a
01:49bit more easy to read.
01:51So, after the case 40, without the curly braces, I can just execute the code I want it to do.
01:57In this case, let's just do a simple NSLog message.
02:00It's a category 41 or 40.
02:04What's very important that you do after each of your cases, because we are not
02:09enclosing these with curly braces, we have to say now we are done and the way
02:15that we do that is by using the keyword break.
02:18What break will do will take us from this case, line 14, and just jump us outside
02:24of the closing curly brace.
02:26We are done, the case was 40.
02:29We execute our code, whether that was one line such as this case or ten lines, and
02:34then we jump out. We are done with the switch statement.
02:37I could take this code and do something very similar for the next one.
02:44And the reason why we use break is that a switch statement suffers from
02:48something called fall through, which means if we don't break, we will continue
02:52to move our way down the statements.
02:55I will show you the example here.
02:57I'm going to leave individual statements for the case 42, 43, 44 and then just
03:04put a little NSLog message here that says this is a 42 or 43 or 44.
03:14So, in any of these three cases, we are going to execute the same code.
03:19Now finally, while you don't have to do it, there is one other word we can use
03:25called default, and this is found at the end typically and it's basically saying
03:31none of the particular case statements were true.
03:34So, I might write another little NSLog message and again, being good about it.
03:42While break doesn't really make much of a difference here, it's a good
03:45practice to put it in there.
03:46So, right now, I'm setting that equal to 47, so this is the message I
03:51would expect to see.
03:52Let's run it and see what happens.
03:53It says I don't know what it was. Yup!
03:56No surprise there.
03:57If I change the variable itself to, say, case 41, we run it again and it will
04:04say yes its category 41, and now I am going to change it to 43.
04:09Run it and we should have the more generic message that's being spat out.
04:14One more thing-- I'm going to go through with this-- is something that's a bit
04:19pernicious and can cause quite a bit on a weird issue with people, which is if I
04:24put in another NSLog message here saying it's a case 42.
04:33Now, I'm going to change the value of this variable to 42. We are going to
04:38come into the switch.
04:40We are going to check the different values and this will be the first one that
04:43should be regarded as true.
04:46So, I will execute it.
04:48Click Run and if I take a look at the message that I get, you can notice here
04:52I am actually getting two messages being output.
04:55It's case 42 and then it's 42, 43 or 44.
05:00The reason for having that is because I didn't have a break here.
05:05So, while we did hit this line and execute this line, we then fell right
05:10through to the next one as well. That may have been what I wanted, that may not
05:14have been what I wanted.
05:16And as a general rule, breaks are really good things to have.
05:20You will find, in fact, in other C based languages like C#, they actually
05:25don't allow you to fall through and so you have to have breaks after them.
05:29Otherwise it causes a compile error, simply because over the years fall through
05:33has been the cause of many bugs that are quite hard to find, because the
05:37compiler will never complain about them.
05:39Most old-school C programmers become very conscious of always taking a second
05:43look at any switch statement just to make sure it's got enough breaks in it.
05:47But as you can see, because this is really all working at the same level that
05:51becomes a very scannable, very readable way of checking multiple values for
05:56the same condition.
Collapse this transcript
Code snippets
00:00If you're new to C-based languages and not yet confident of your braces and
00:04parentheses and semicolons all being in the right place, here's an easy way to see the syntax.
00:09We are going to use something that's baked into Xcode called code snippets.
00:13These are part of the utilities section that will appear on the right-hand side of Xcode.
00:17So to bring them up, I am going to click this third button in the View section
00:22that toggles the Utilities panel on and off.
00:25And all you will find is down here at the bottom, we have another section that's
00:29broken up into four pieces that gives us templates, and then if I mouse over the
00:33curly braces, we have the Code Snippet library.
00:37I am going to drag this up to make it a bit more viewable here. And there are a
00:41whole bunch of built-in code snippets that Apple has already defined for us,
00:46including things like an if statement or an if else statement.
00:50Now, if I mouse over one of those, it can show me that this is showing an
00:55if-else Statement, if condition statements-if-true, else statements-if-false.
00:59So let's say that's what I wanted.
01:01I can grab this and just with my mouse held down just drag it over to the
01:06position that I want to have it.
01:07Let's say below the NSLog and let go.
01:11Now, it drags it in with little placeholders for the condition that I'm asking for.
01:16Now, the whole thing is actually selected right now as you can see by the blue
01:21outlines, so typically the best thing to do is just press your left cursor key
01:26to go right to the start of the If Statement and then by hitting Tab I can just
01:31jump to the condition.
01:33So let's say I had a variable called A and I wanted to see if A was less than 10.
01:37I could do that. I could then hit Tab again, jump down to
01:41statements-if-true, I will just put some simple comment here and hit Tab again
01:47put the statements-if-false to some other stuff.
01:50It's a very easy way to start to bake that out.
01:53Now, you will often find that right now, at least with Xcode, it kind of messes
01:57up the indentation a little bit.
02:00So what you can do is grab that whole if statement, or any block of code,
02:05and then you can right-click it or Ctrl+Click and here in the Structure
02:09section you have something called Re- indent, which you can also use Ctrl+I as
02:15a shortcut and what that will do is bring that into line with the rest of your
02:20code with proper indentation levels.
02:22Again, it doesn't have to be a code snippet to use that on. You can do that
02:25with any block of code.
02:26So if you mess your own code up, you can just hit Ctrl+I after you have selected
02:31it to re-indent everything.
02:33Now, right now it's complaining about the fact that I don't actually have
02:36a variable called a, which is fine, because I just wanted to show that as an example.
02:41So we have if-else statements, we have if statements.
02:44If I come down to the bottom to the little search box here, I could say type in
02:49the word switch and it says, yup, we have got a switch statement as well.
02:52I can grab that across and drop that in and it gives me now the good reminder.
02:57Again hitting the left cursor, just go the start, I can hit Tab and switch on
03:02the expression and then just hit Tab to jump between the different pieces, but
03:07it gives me a reminder to break each case statement and to break the default case statement.
03:13Going back over to the Code Snippet library, I am just going to come down and
03:16get rid of the search, the little thing that I am filtering on.
03:20And you might notice that some on the snippets say C Block, C Inline, C++, Core
03:28Data, Objective-C, and some snippets don't actually have a language. In fact,
03:34the switch statement that I use, doesn't say Objective-C, doesn't say C++,
03:38doesn't say C. That's simply because it doesn't matter at all. Things like a
03:43switch statement and if-else statement are written exactly the same way in C
03:47and C++ and Objective-C.
03:49Now, after a while of course, you won't need snippets for simple things like
03:53switches and if-else statements but there are also pretty big code snippets if I
03:58come into say the Core Data Fetch with a Predicate, which right now I would
04:03fully expect you to have no idea what that meant. But if I drag that across,
04:07we can see that it's adding a whole bunch of code that would be quite nice not to
04:11have to manually type ourselves.
04:13Now, I certainly don't need that right now, so I am just going to hit my
04:16Delete key to get rid of it.
04:17Now, one of the things you can actually do is create your own.
04:20You can find any piece of code that you have that you want to save.
04:24So, when you're learning Objective-C and you want to remember certain pieces
04:28that you're trying, you can simply grab it, hit your key, hold down the mouse
04:32button, and drag it over into the Code Snippet library.
04:35What it's going to do is give you your own code snippet here that you can edit
04:41and give it a title.
04:42I can just call that one Hello World, not that I really need a snippet for that.
04:46I'm just going to leave the rest of it because we'll come back to code snippets
04:50a little later when we are doing some more advanced code and you'll now find
04:53that you have a Hello World code snippet that you can just come along and drop
04:58into any program that you have.
05:00So they can be used a lot for just reminding yourself of syntax while you're
05:04learning this language and then as we get into more advanced pieces of the
05:08language, they're certainly great shortcuts for creating some more complex
05:12code that needs to be repeated all the time.
Collapse this transcript
Operators and expressions
00:00As in any programming language, we spend much of our time in Objective-C writing
00:04expressions, using operations to calculate, move, add, subtract, or compare, and
00:10to perform these operations we need operators.
00:14One of the most obvious are probably the arithmetic operators and we have the
00:17usual suspects here: the plus sign for addition, minus for subtraction, asterisk
00:22for multiplication and forward slash for division, often of course used in
00:26conjunction with the assignment operator or equal sign to evaluate an expression
00:32on the right-hand side, in this case, a+b, and then take that and put it in
00:37whatever's on the left-hand side, in this case a variable called result.
00:41You can of course use the same variable names on either side of the equal sign.
00:46In this case, we are saying that we want to set score to whatever it currently
00:51is +10, and this kind of operation is so common that we have a shorthand for it,
00:56which is the plus equals operator simply to add 10 to the variable score.
01:01Now, it makes sense that if we have a plus equals operator, we also have a minus
01:06equals and a multiplication equals and a division equals.
01:10And bear in mind that these are considered single operators.
01:13There is no space between the plus and the equals or the minus and the equals
01:18and son on, but they can be a useful shorthand.
01:21Now, as with most languages, there is operator precedence in Objective-C.
01:26Simply speaking that means some of these operators are treated as more
01:30important than others.
01:31The classic being that the multiplication and division are regarded as more
01:36important than addition or subtraction.
01:38What that means in this example is that if you simply read the expression left
01:43to right, you might think that 5+5 is 10*10 is 100.
01:49So, results should be set equal to 100 but no, of course, the multiplication is
01:54regarded as more important.
01:55So, we would first do the 5*10 as 50 then we would add 5 to it and the result
02:01would actually be 55.
02:03If instead, I want to impose my own order on how this is evaluated, I simply
02:09take the important pieces and surround them with parentheses.
02:13In this case, I want to say that (5+5) needs to be evaluated by itself.
02:18That will impose our own order on it.
02:20We will have 10*10 and the result will be 100.
02:24So, the parentheses not only used to make these expressions more readable, but
02:28to impose our own order on operator precedence.
02:32Moving on we have comparison operators via quality check.
02:36Again, if we are asking a question, if we're checking that one thing is equal to
02:41something else, we are using two equal signs.
02:44Two equal signs is when you're asking, one equal sign is when you're telling.
02:49If we want to know if something is not equal to, we have got the inequality
02:53operator, which is the exclamation mark equal sign.
02:56Again, both of these are regarded as single operators.
02:59They cannot have a space between them.
03:02While we are talking about comparisons, we also have the greater than sign,
03:05we have the less than, we have greater than or equal to or less than or equal to.
03:10All of these operators will perform these actions and simply return a true or
03:15false or a yes or no, positive or negative, whatever way you want to think about it.
03:19Well, if we are interested in conditions, oftentimes we will have multiple
03:23conditions where we'll use the logical And and logical Or.
03:27In this case, I have got an if statement.
03:28I want to save if a = b and c = d, then I am going to perform some code, so we
03:35will use the two ampersands for the logical And.
03:39For the logical Or where either of these can be true to succeed, we are
03:43using the logical Or.
03:44It's the two vertical bars or pipe symbols.
03:47Again, these are single operators.
03:48There is no space in between the ampersands or the pipes.
03:52Complex statements like this are often spread on to either multiple lines or
03:57surrounded with parentheses.
03:59Again, this makes it easier to read and it's one of the benefits of white space
04:03being insignificant here.
04:05Now, a couple more operators to cover.
04:07One is called the modulus operator.
04:09It really just looks like the percent sign.
04:11I still run into a few folks that haven't used this one.
04:14This is used to calculate a remainder.
04:16Let's say we have an integer variable called year set equal to 2003.
04:19I am going to create another integer variable called remainder and set it equal to year % 4.
04:27What this does is, it divides the variable year, the value of 2003 by 4 and then
04:32gives us the remainder.
04:33It doesn't give us the result.
04:35If I just use the forward slash, the result would be 500.
04:39If I use the percent sign, we throw away the 500 and say well, we got a remainder of 3.
04:45The modulus operator only works on integers.
04:48The classic example of using this is to calculate leap years or calculate odd or even numbers.
04:54Next up, we have the ability to increment or decrement and we have kind of done this already.
04:59We have already seen that we have the plus sign.
05:02We could say a=a+1. We are incrementing the variable a. And we have even seen
05:08there is a shorthand for this plus equals but we have even more of a shorthand,
05:12which is just plus plus.
05:15a++ is regarded as a unary operator.
05:18What that means is it just needs one thing to work on.
05:21all the other operators we have talked about so far are binary operators.
05:25They need to things to work on.
05:27We can write this as a++ or ++a. If I was writing them on their own lines,just
05:34like this, they'd both do exactly the same thing. They are adding 1 to a.
05:38That makes sense that if we have got increment operators for plus plus, we also
05:43have the ability to decrement.
05:44Yes, we could do it by saying a=a-1 or a-=1 but we have the shorthand a-- or --a.
05:55Again, on their own lines like this, they would do exactly the same thing.
05:59They are just simply going to subtract 1 from a.
06:03The question might be well, why do they have two different versions?
06:06Why do they have the minus minus before and the minus minus after or the plus
06:10plus before and the plus plus after?
06:12And if you want to get geeky about this, this is known as the prefix and postfix operators.
06:18And there is a little tricky impact to them because there's a difference if
06:22these are used embedded in another statement say in an if statement or an NSLog message.
06:28Let me explain the difference here.
06:30Let's say we set up by creating an integer variable called a, set it equal to 5.
06:34That's going to carve about 4 bytes of space in memory and put the value 5 in it.
06:40I then write another statement, an NSLog message that says the value of a is,
06:45comma, and we give it ++a. This is the increment operator.
06:50it's the prefix version that's before the variable name.
06:53What happens is when we are running this program, we hit the NSLog line.
06:58It looks at that ++a and it says, ah, I add 1 to a. So it first adds 1 to a, a
07:04becomes 6, and then it executes the rest of the line and says the value of a is 6.
07:11This is the prefix version of the increment operator.
07:15If I back this out, let's go back to having a = 5 again and instead I use an
07:21almost identical line, but I use a ++, the postfix version of this where the ++
07:27is after the variable name,
07:29well, what happens is the line will execute but we will first output the
07:35message and only after the line has been interpreted we will then add 1 to a and a becomes 6.
07:43The prefix and postfix versions of increment and detriment are one of these
07:47little things that can cause bugs that are quite hard to find.
07:51So, I tend to only use these operators by themselves on their own line.
07:56Then it really doesn't matter.
07:58When we have executed the line of code, it's either been incremented or decremented.
08:02Just be aware that if they are inside a say an if statement or a statement like
08:06this NSLog message, that you might not get exactly what you expect.
08:11And finally, this last one is a great little useful one called the ternary operator.
08:16We have unary operators that work on one element, binary operators that work on two,
08:21and ternary that work on three.
08:24So, what happens is the ternary operator has three parts to it and two symbols,
08:30the question mark and the colon.
08:33It looks a little strange here but do bear in mind that this whole operation
08:38will result in one single value.
08:41This will be evaluated and return some thing.
08:44In fact, you can think of the ternary operator is kind of like a mini if-else statement.
08:49Let me show you an example of how this works.
08:52Let's say I have written a little bit of code here to set up a couple of
08:55integers somewhere in my program: playerOne score and a playeTwo score.
09:00And we can imagine that these are being changed and these are being incremented
09:03and the values are 400, 500, or 600, who knows.
09:07Later on, somewhere in the code I want to create a new variable called
09:11highScore and I want to set it to whatever the bigger one is.
09:15So, I might write an if statement that says if playerOne is greater than
09:19playerTwo, I will set highScore to player one. Otherwise, I will set highScore to playerTwo.
09:24Yup, fairly simple code here but we are still using 1, 2, 3, 4, 5, 6, 7 lines,
09:31not even counting the space, just to set up a variable value.
09:35So, using the ternary operator, I can kind of compress this all down to one line.
09:40What I'm going to do is replace this highScore declaration and say I want to
09:45create a high score and I'm going to use the ternary operator to immediately set its value.
09:52Ternary operator has three parts: the condition, question mark, what if it's true,
09:57colon, what if it's false.
09:59So, I am going to grab the condition from the if statement, so just copy that up there.
10:03Condition is playerOne > PlayerTwo, then I write the question mark.
10:08Then I say what is this if it's true?
10:10I am just going to return the value of playerOne, add a colon, and then what will
10:16I return if it's false?
10:17I will return playerTwo.
10:19We end the statement with the semicolon, and what this actually means is I can
10:24get rid of that if statement. I don't need it anymore.
10:27Simply by using that ternary operator, we really get this mini if-else
10:33condition going on.
10:34We check the condition. If playerOne is higher, we will return playerOne;
10:38otherwise we'll return playerTwo.
10:40Now yes, there are a few other more esoteric operations.
10:44We do have things like bitwise operators in Objective-C that can work on
10:49shifting individual bits around inside a byte.
10:52I'm not going to cover bitwise operators in this course.
10:55These days many programmers go for years without needing to do
10:57bitwise arithmetic.
10:59If you need them, they are there, go look them up, but the ones we've just
11:02explored should certainly be enough to get us moving on and building some
11:06useful logic in our code.
Collapse this transcript
Loops
00:00Like writing if statements and conditional code, you really don't get very far in
00:04any programming language without needing loops or iteration.
00:08And the idea is simple.
00:09We have a little bit of code, maybe it's one or two lines, maybe it's a dozen,
00:14maybe it's a hundred, and we want to repeat this.
00:17Well, we could just copy and paste it and do it again and do it again.
00:22What would be a much better way of doing it is to be all to take those two lines
00:26or a dozen lines, make a block out of them, and then just say repeat this 5
00:31times, or 5000 times, or just keep on repeating until something changes.
00:37Or more generically, process all entries or process every address in my address book or
00:42for each photo in my photo library perform these actions.
00:47Setting up loops in Objective-C is easy.
00:49In fact the main issue with any loop is not when to loop; it's when to stop.
00:53So how do we do that?
00:54Well, the format is pretty much identical to working with say an if statement.
00:59If take a look at basic if statement here, we're asking if, then the condition
01:04is in the parentheses and then we have the opening curly brace, our statements,
01:09one or a dozen, and our closing curly brace.
01:13To change this into a loop I simply replace the word if with the word while.
01:18And this one says while this condition is true, I will just keep looping around
01:23the statement block.
01:25So we have a very simple loop here.
01:28In fact, we have an infinite loop here.
01:30If I run this right now what's going to happen is we're just going to keep
01:33looping around and around and around, until somebody presses the stop button
01:39and kills this program.
01:41Because of course, the problem is this condition on line 12 is always going to be true.
01:47a will always be less than 10 unless something changes a in the body of the loop.
01:53That's a very common thing that you'll see towards the end of a while loop is a
01:57line like this, a++.
02:00We run this one again and what's going to happen is we're going to go around
02:04from 1 to 9 because when a hits that last ++ and it becomes 10, the condition is no longer true.
02:13So we jump out of the loop and start continuing from the closing curly brace onwards.
02:19This is the most basic kind of loop in Objective-C.
02:23There is a variant of the while loop called the do while loop.
02:28The real difference here is simply that we move the condition to the end.
02:32I could convert this while loop into a do while by selecting the while part in
02:38the condition, cutting that out, changing it to the word do, and then pasting in
02:44the while at the end.
02:45Now I do have to add a semicolon to close this.
02:48In fact, if I run this now I would get an identical result to the result I got
02:53from just having while.
02:55However, the big difference between a while and a do while is that with a do
03:00while this statement block will always be executed once, even if the condition is false.
03:07So in this case if a starts off with a value of 1000, even though the condition
03:13says we do this while a is less than 10, we're still going to run through an
03:18output that message once.
03:20That's very different from just a while statement.
03:23Converting this back into while and get rid of that closing semicolon, we can
03:28run it and in fact it will run and Xcode is detecting there is no output from
03:33this program so I am not even getting the debug area popping up.
03:37You'll find that while loops like this one are much more common than the do while loops.
03:42In the code I've written over the years, I'd guess I would write 100 or 200
03:45whiles every do, because in most loop it is expected to check the condition
03:50before you enter the loop, and it's much more readable to have the condition
03:54at the top of the loop rather than at the bottom, particularly if you've got a lot of code.
03:58So while loops are very, very common and in fact in many loops a pattern
04:04emerges, because we start to notice that we really need to set up this while loop
04:10with a counter or an index going into it.
04:13In fact, you'll find it very, very common that an index variable will be set up called i.
04:18And then of course, the loop itself needs a condition that it's going to be
04:22checked every time we go around the loop, every time we iterate, and then within
04:26the body of the loop itself, usually right at the end, is the increment of the
04:31index to make sure that we're keeping track of the right position.
04:35In fact, having these three pieces is so common that there is another statement
04:40that brings all these pieces together.
04:42It's creating a for loop.
04:44Again, it keeps the generic framework of a while or an if in that it's the
04:49word for, then an opening and closing parentheses, and then an opening and
04:54closing curly brace.
04:55However, within the parentheses things look a little different.
04:59We actually have three pieces to it, the same three we needed for the while loop.
05:04We set up the index, often referred to as the initializing phase.
05:08In this case create an integer called i and set it equal to 1.
05:12Then we check the condition, is i less than 10? Yes, it is.
05:15We'll go through the loop.
05:17At the end of the loop, we'll jump back up and hit the third part of the
05:22statement which is the incrementer.
05:24It's very common to have the ++ here, but you don't have to be incrementing by 1.
05:28You could be adding 50 or a dozen or 107 if that made sense.
05:33The big benefit of this is it is very readable.
05:36Everything about the loop is right there, inside these parentheses.
05:40We don't have to look outside the loop for the index being set up nor do we have
05:45to scan inside the body of the loop to make sure the increment is happening.
05:48So this is a very common way of seeing loops written in Objective-C,
05:53particularly if they're number based.
05:55You want to do something 1000 times or 500 times.
05:58Now to wrap this module up, there are two words that you will occasionally run
06:03into when working with loops. Not all the time, but you'll see them.
06:07That's the word break and the word continue.
06:10Let's take break first.
06:11In fact, we've seen break used before.
06:13It was used in a switch statement and it meant we're done with the switch
06:17statement, jump out of the block.
06:19And that's really what it means here too.
06:21If inside the body of the loop we see the word break and it's just break by
06:26itself, there's nothing else needed, we will jump right back out to the end of
06:30the loop and continue as if the loop had fully finished.
06:33So in this case we're setting up a loop that should go around 5000 times, but
06:38inside the body of the loop there's an if statement.
06:40If i is equal to 101, break.
06:43And if we ever hit that line we're going to jump completely out and say we're
06:47done with the loop and move on forward.
06:50The other word that you'll see from time to time is the word called continue.
06:55Like the word break' it's just used by itself, on its own line as its own statement.
07:00The big difference between the two is that break jumps out of the loop and says
07:05we are done with this for statement or this while or this do, where as continue
07:11says no, we're just done with this iteration and jump back up to the top and
07:16check the condition again.
07:18It might look a little strange here, so let me show you what the impact of this is.
07:22So I've got a very simple for loop beginning on line 10 here.
07:25We're setting up with integer i equal to 1.
07:28The condition we're checking is i is less than 5000, and then the increment is i++.
07:33Inside the loop I have a simple if statement. If i divided by 5 leaves a
07:38remainder of 0, I am using the modulus operator there, then we're using the word continue.
07:44What that should mean is every time i is a number that's cleanly divisible by 5,
07:50we're not going to continue on to line 16 and hit NSLog.
07:53We're actually going to jump back to the start of the loop and go around again.
07:57So let's see the impact of this.
07:59I run it, it loops around just about 5000 times, but if you scan the numbers
08:05what you're going to see is we're going from 1, 2, 3, 4, 6, 7, 8, 9, missing 0, and going to 1.
08:11So every time this number is cleanly divisible by 5, either ending in 5 or 10,
08:17we're skipping the NSLog message.
08:20Yeah, a very simple example, but hopefully that should get over the point of
08:23continue. continue will always jump back to the top.
08:29It doesn't cause the initializer to be executed again.
08:32We don't reset i to 1, but we do check the condition again.
08:36You won't need break or continue in most loops, but you will see them from time
08:40to time and you need to know what they mean.
08:42Now there are a couple of the other loop types that we get to later in the
08:46course when we have a bit more data to play with, but these three are essential
08:51for us to move forward.
Collapse this transcript
Functions
00:01As we add more code, it will get more complex to read and understand and as
00:05with all languages, we'll break apart larger amounts of code into smaller
00:09modular reusable pieces.
00:12Now there's a couple ways to do that in Objective-C, but right here and right now,
00:15that means we're going to create functions.
00:18A function is simply a chunk of related code wrapped up and given a name.
00:23Now right now I am looking at kind of a pseudo code example.
00:26So let's see really how to do this in Objective-C.
00:30To create a function, we start off with the code that we're interested in.
00:34Whether that's 1 line, 10 lines, a dozen, or a hundred, we wrap that in another
00:38statement block, the opening and closing curly brace, and we give it a name.
00:43In some other languages, you might need to actually type the word function or procedure.
00:48You don't here. You just give it a name like createMessage, or saveSettings,
00:53or connectToDatabase. It's up to you.
00:56You'll commonly see this written in CamelCase format.
00:59If there is multiple words, the first one will start lowercase, every
01:02subsequent one will start uppercase.
01:05Objective-C doesn't really care.
01:07It's just common practice.
01:08So I'll call this something generic like myFunction, but we're not done yet.
01:13We have two more pieces of information to add, to make this correct.
01:17So I am going to give myself a bit more space before the opening curly brace and
01:21put in an opening and closing parentheses.
01:24This is where we define any parameters to this function.
01:28When this function is called, do we pass it in some information, and like what?
01:33We'll say we want to call it passing in an integer because we want it to perform
01:37some operation on an integer.
01:39Well, we put the type, which is int, and we give that a name like x or foo or
01:44myVariable or myParameter.
01:47We use the same naming conventions as we use for creating variables.
01:52If I wanted to pass in multiple ones, I would give a comma in between them.
01:58In this case we're saying we expect two parameters passed in.
02:01We'll call one x, we'll call the other one y, and those would be the names that
02:05you would use to refer to those values inside the body of the function.
02:08Now you don't have to take any parameters. You can just use the word void
02:14instead to say explicitly that this takes no parameters, or you could just leave
02:20that empty and have the opening and closing parentheses.
02:24But even if it is empty you still need to have those opening and
02:26closing parenthesis.
02:27I got one more piece to add here, so I am going to create a bit of room at
02:32the start because, before the name of the function we're going to add the return type.
02:37Does this function send something back?
02:40And again, like what?
02:41Well, let's say we want to return an integer value.
02:44I'll put a return type of int and all I do here is give it the type. I don't
02:50give it a name because that will be up to whoever is actually taking this value back,
02:54but I say do we return an int or a float or a char?
02:57Now if I say that I am going to return an int, well I better have some code in
03:02the body of the function that actually does that.
03:04And typically speaking, in the last line you'll have something like this:
03:08the word return and then well, what are we returning?
03:11I said it's an integer, so I better return say a 0.
03:14That's common for meaning this was successful.
03:17If you had a lot more complex code you might be returning error codes, which are
03:21completely up to you.
03:22If you wanted to return 99 you could do that too.
03:25But as soon as you hit a return statement, we are done with the function.
03:30Now what if I don't want to actually return anything?
03:33What if I just want this function to write out some messages or save
03:36something to a database?
03:37Well, I don't have to say int.
03:39I can say void and that's how we would explicitly say this function returns no value.
03:44Well, then that better not be returning a 0.
03:46So I am going to change that just to the word return, which you can do for a void
03:51function, but actually if it is void, you don't even need anything.
03:55You can allow the function just to get to the closing curly brace and that will
03:59count as the end of the function.
04:02So this is the general format of a function in Objective-C.
04:06And we already actually have one.
04:09Main is a function.
04:11This is the default function that you have in your program.
04:14On line 3 here we're saying that this is a function called main.
04:17It returns an integer and it takes two arguments here, one an integer called
04:22argc and the other which is this rather odd looking const char and then the little
04:27asterisk representing a pointer and an array here.
04:30Now, that looks a little weird.
04:31We haven't really gone into that format yet so you can just ignore it, but we
04:34can imagine that this is a main function that takes two arguments and returns an integer,
04:39and if you see on line 18, that's where we have return 0.
04:44main is the only function that will be called automatically.
04:48Every other function, we actually have to add the code ourselves to call it, but
04:52before we call it we need to create it.
04:55So what I am going to do is I am going to take a block of code that I have here
04:58from line 10 to line 15 and make a function out of that.
05:03So up here after the #import but before main and completely outside main, I am
05:08going to create a void myFunction. I'm going to say a simple one here so it returns
05:14void and takes no parameters.
05:16I have my opening and closing curly braces.
05:19And I am going to come down here into main, grab that code, cut it out, and
05:23paste it up here into the body of the function.
05:26Well, right now this should compile, but I am never calling my function.
05:31The only thing again that gets called automatically is main.
05:34So where I did originally have that code I am now going to replace it with a
05:38call to myFunction and I can even see that I am getting the Code Sense, the code
05:42completion popping up here.
05:44So I'll type in my. I'll just hit return to accept that.
05:47Put the closing semicolon, save it, and run it.
05:53Build Succeeded and we get our little 5000 loops popping out.
05:56Function is no very exciting, but it'll do to prove what's working here.
06:00Now what's quite common is that you don't always want to put all these
06:04functions up at the top.
06:06So what would happen for example, if I took this function and cut it from here
06:10and then pasted it below main?
06:12Well, in some languages it wouldn't really care.
06:15But in this one, it does.
06:17Build has failed because as the compiler is moving through it's saying "Well,
06:22I got to line 13 which is calling myFunction" and it's complaining about this.
06:27Implicit declaration of function 'myFunction' is invalid in C99.
06:31Complex error message there, a warning, but it really says "I have no idea
06:35what myFunction is."
06:37Now there's two ways to handle this.
06:39one is I just take the definition of the myFunction function and move it back up
06:43to the top, but if I don't want to do that, if I wanted to keep it a bit tidier,
06:48what I could do is just describe the function up here.
06:52And that sounds a little weird if you've never done that before, but all it
06:55means is I would describe what the signature or the description of the function is.
07:00So I would say void myFunction, open and closed parentheses, semicolon.
07:06There is no body of the function here.
07:08All I am telling the compiler is "Hey, by the way there's going to be a
07:12function called myFunction.
07:13It takes no parameters and returns void.
07:16So when you see it being used, don't worry about it."
07:19I still do need to define what that function is which we have defined now in
07:23line 19 down here, but this would allow this program to compile.
07:28The build has succeeded and when we run it it's going to run just fine.
07:32Now doing this is what's referred to as a function prototype.
07:36On line 4 all we have is a description that the function exists, what it returns,
07:41and what it exempts, but nothing in the body.
07:44Now on this very simple example like this it really doesn't matter all that much,
07:48but what you'll see is this ability to have these prototypes to describe
07:53the functions and the capabilities that exist can come in very handy later on.
07:57We would use that a lot when we get into the object oriented side of Objective-C.
08:02Now what you'll often find very common is that you're going to be doing functions this way.
08:07You'll be taking code that exists somewhere else, copying and pasting it there.
08:12And that can a get a little tedious so there is something that can actually help us out.
08:15If you'll let me take this back a little bit into the way it was a few minutes ago,
08:20where there was no separate function, we just had main.
08:24Now here's a cool thing that can make it easier.
08:26Xcode can help us make those functions from code that we might have
08:30written somewhere else.
08:31I am going to select that code and then I am going to right-click or Ctrl+click it
08:36and what you'll find is this a Refactor option here.
08:40This is going to allow us to Extract that code and create our own function.
08:45So I hit Extract and it's going to take a little look at it and say "Okay, let me
08:49try and figure out what you want to do.
08:51I presume that what you want to do here is create a function." extracted_function
08:55is kind of an annoying name that would work, but I am just going to say well, I
09:00wanted to call it myFunction.
09:00I am going to hit Preview.
09:03It's going to tell you exactly what it's going to do here, that it's going to
09:07create a new void myFunction that takes void. Yeah, looks okay.
09:11So I quick Save. It pops up a little message here.
09:14The first time I've seen this. Would I like Xcode to take automatic
09:18snapshots before Refactoring?
09:20Basically a snapshot is just a point in time state of your project.
09:25You can say Enable.
09:26I don't want to get too much stuck with snapshots right now so I am going to say Disable.
09:30There's no big deal there.
09:31I am just trying to keep my setup as simple as possible.
09:35And then we see here that we've got the void myFunction.
09:38Xcode added the word void in this parameter section.
09:42I don't have to have that, but it is okay just to leave it there.
09:45And where I had originally had the code, you see that Xcode has replaced it with
09:49a call to that function.
09:51It's not indented properly, but that's fine.
09:53In fact, I am just going to do highlight all the code here by hitting Command+A,
09:57and then just hit Ctrl+I to do indentation of it automatically.
10:03And as we get even more complex we'll start managing our project by breaking our
10:08code out into completely different files instead of having them all in one file
10:12called main.m, but for now, this will do.
Collapse this transcript
4. Variables
Data types
00:00In all programs we need to keep track of dozens, hundreds, thousands of pieces
00:04of data. Email addresses, the color of the background, the position of an object
00:08on the screen, the amount of time the program has been running.
00:11So we create variables to hold that data.
00:14A variable of course is simply a named container.
00:18It's a container that represents a piece of computer memory set aside for us to
00:22use while the program is running.
00:24As in real life some of these containers can be smaller and some of these
00:28containers can be bigger.
00:29Some containers hold one kind of substance. Other containers hold the same
00:34substance, but less of it or indeed more of it.
00:39And other containers well, sometimes it's a bit more difficult to figure out
00:42what these ones hold.
00:43You may have to look a little deeper to figure out what's inside some of them.
00:47And this is the same in our program.
00:49We have these containers in memory.
00:51Some of them will contain integers.
00:53these are numbers without a decimal point.
00:55Some will contain larger integers.
00:58Some will contain numbers with something after the decimal point.
01:01Some will contain characters.
01:03And we can create more complex variables that contain combinations of the above.
01:09Now if you're coming from a language like JavaScript, you may be familiar with
01:13creating variables like this where you can start off by defining a variable
01:17called foo and setting it to be a string and then deciding to change it to a
01:22number and then back to a string.
01:24This is not something we do in Objective-C.
01:26We will type our variables.
01:28Now to recap in Objective-C we define variables like this.
01:33Every variable has a type,
01:34it has a name and it has a value.
01:37The value is the part that can change.
01:39It can vary, hence the name variable.
01:41So to create a variable called highScore that can hold an integer, we use
01:45the type int or int.
01:48This is all lowercase.
01:49It's part of the language.
01:51Actually it's part of C so it's automatically part of Objective-C.
01:54We'll talk about the other available types in a moment.
01:57Now when it comes to naming our variables well, we can start off by playing
02:01around and creating variables called a, b, c, or common nonsense words like foo
02:07and bar and this is because right now these names don't mean anything.
02:11But in your programs they're going to represent high scores and account
02:15balances, names and dates, latitude and longitude.
02:19So we name them so they make sense later when we or someone else reads this code in a year.
02:24Now every programming language tends to develop its own style guidelines
02:28for naming variables.
02:30And we'll talk more about style guidelines later in the course, but for now in
02:34Objective-C this is what we do.
02:36We name variables with CamelCase.
02:39We begin with a lowercase letter and if there are any subsequent words, we'll
02:43start each one of those with an uppercase letter like the hump of a camel.
02:48Variable names are of course case sensitive.
02:50Everything is case sensitive in Objective-C.
02:53Don't be afraid of long variable names.
02:56Long variable names are quite common in Objective-C and we have code sense in
03:00Xcode that will help us automatically complete long variable names later.
03:05If you're coming from a language where they use some other standard like
03:09prefixing variables with their type or using underscore between words, know
03:14that there is nothing that will stop you from doing that in Objective-C, but
03:18it's not what Apple will do.
03:20And that's important because you're going to need to read Apple documentation
03:24and view sample code and read online discussions.
03:28And they're pretty much all going to do it the way the first four are here.
03:32So do jump in, try and name your variables the Apple way, and it will make
03:36it easier when it comes to naming other parts of our program like methods and classes.
03:42So back to that integer. Well, when this program runs this line it will allocate an area of memory.
03:47In this case 4 bytes,
03:49an integer is always 4 bytes, and sets it to this value of 100.
03:55And the maximum value of this highScore variable the way I've written it
03:59is about 2 billion.
04:00That's the max value of a regular int variable in Objective-C.
04:04There is a bit more to integers, but we'll see that in a moment.
04:07So what other types of data can we have in our variables?
04:10Well, because Objective-C is built on top of C we have the same primitive data
04:15types as the C language.
04:17We have int, we have float, we have double, we have char. int we've seen.
04:24float is a floating-point variable.
04:26Either a number that's too large, small, or inexact to be represented as an integer.
04:31double is also for floating-point variables.
04:33It simply double the size of a float.
04:36And char for single characters.
04:38Now officially in Objective-C, we then have all those same data types.
04:44There is also a Boolean data type and it's written in Objective-C all
04:48uppercase as BOOL.
04:50Technically it's really a char under the hood, but we can account it as being
04:54one of the built-in data types.
04:56And we'll cover all of these in the next few minutes.
04:59But that's pretty much it for data types.
05:01And you might think well, hang on, what about more complex data types?
05:05What about dates and pieces of text longer than one character?
05:08What about images or buttons or menu items?
05:11Well, these, the int, float, double, char, BOOL, are built into the C and
05:17Objective-C language.
05:18They are what are often called primitive types.
05:21And many other data types could be considered combinations of the primitive types.
05:26For example, you could say that a date could be represented by several integers,
05:31one for year, one for month, one for day or, it could be represented by one
05:36integer that's simply the number of seconds since the 1st of January, 1970.
05:40You might think I am kidding here, but this is UNIX or POSIX time.
05:44It's a very common way to represent a date and time on a UNIX system.
05:48It means we can hold a date and time internally in a single integer variable.
05:54Now if we're working with text or strings, well, they are at their core simply a
06:00bunch of single characters strung together.
06:03Even if writing them like this would be very tedious indeed. And string is not a
06:08built-in data type in Objective-C.
06:11A date is not a built-in data type in the Objective-C language, but that doesn't
06:16mean we don't have strings and dates. We do.
06:19Apple took the core of the Objective-C language and they wrote code to make it
06:24easy to work with strings and dates and images and video and menus and buttons
06:28and hundreds of more complex types.
06:30But these are part of the frameworks we can use, not part of the language itself.
06:36So for example, there is an NSString type that we can use.
06:40There's an NSDate type that we can use.
06:43These are classes that have been written using Objective-C.
06:48But they're not like primitive types like ints and floats.
06:51And the process of creating and using variables that hold say strings and dates
06:56is very different from ints, floats, chars, BOOLs.
06:59So we're going to get to these, but we're going to get to them later.
07:03Let's begin with the primitive types and build on those.
Collapse this transcript
Working with numbers
00:00So we've seen int, the classic integer variable in C and Objective-C.
00:05This holds whole numbers, takes up 4 bytes or 32 bits.
00:09That's important solely because it affects the range.
00:1332-bit, 32 of these little 1s and 0s turning on or off, can hold roughly 4.3
00:19billion possible combinations.
00:21Because ints are signed by default, meaning they can hold both positive and
00:26negative numbers, that gives us an effective range of about -2.1 billion to +2.1 billion.
00:33If I knew that a variable of mine could even have the slightest chance of
00:37getting smaller or larger than this, then a regular int isn't going to cut it.
00:42So what alternatives do I have?
00:43Well, for start, if I knew that I didn't need negative numbers, I could add
00:48what's called a modifier to this variable declaration and I could add the word unsigned.
00:53That simply gives us the roughly 4.3 billion combinations from 0 upwards,
00:59allowing me a larger range here.
01:01But what if I need more?
01:03Well I can use a different modifier.
01:05Instead of unsigned, I'm going to add the word long and make a long integer variable.
01:11Now the range of this is hmmm, -2.1 billion again to +2.1 billion.
01:18This is the strange one.
01:20You see, when you create a long int it matters how you compile or build your project.
01:26If you compile for 32-bit, a long int is exactly the same as an int.
01:31It takes up 4 bytes.
01:33However, if you compile for 64-bit, then it takes up 8 bytes and gives you a
01:39range of-- well let's just say it's fairly large.
01:42This is the only datatype that matters how you're compiling your project.
01:47So what do I do if I have say 32- bit and I want a very long integer?
01:52Well, what you can do is add the modifier again.
01:55You can make what's called a long long int.
01:58That takes up 8 bytes on 32-bit and 8 bytes on 64-bit.
02:04So it's the same on both.
02:06So a regular int is always 4 bytes.
02:09A long, long int is always 8 bytes.
02:12And a long int depends on whether you're 32- bit or 64-bit, which is why I avoid long ints.
02:18If I need a bigger integer value I'll always make a long, long int.
02:21Now you'll sometimes hear these referred to just with the word long.
02:25In fact, you can actually leave the word int out when you use the word long.
02:29You can make either a long or a long, long.
02:33I prefer to be explicit and say int, but just to let you know you can do that.
02:37And you could also add the modifier unsigned in front of these as well, giving
02:43you all positive values.
02:45If your concern is that you actually want to go the other way, well, you can do that too.
02:49You can add the word short in front of int and make instead of a 4 byte
02:54integer a 2 byte integer, which gives you a much smaller range of roughly
02:58-32,000 to +32,000.
03:01But that's our built-in primitive integer variables that we have to deal with.
03:05What if we did want something after the decimal point?
03:08Well for working with the primitive types, we can work with the float and double
03:12datatypes and I simply use the word float instead of int.
03:16So here I'm creating a float variable called myFloat and I'm setting it equal to
03:207.2 and I am using this letter f after it.
03:24Now it would actually work without the f and I'll explain why in just a second.
03:28But it's a good rule of thumb that if you want to set a float, you use the
03:32little f to be explicit about what you're doing.
03:35There is also the double datatype.
03:38It's also floating point, but uses double the space.
03:41A float is 4 bytes, a double is 8 bytes.
03:44There's your double precision versus single precision.
03:47I'm not going to get into the range stuff here, because we're talking
03:50floating-point arithmetic here.
03:51As on any computer system, you can lose precision with floating-point operation
03:55simply because of the way the computer stores this information.
03:59But that's not an issue for most developers. We won't be doing floating-point
04:02operations in this course.
04:04So what I'm showing here is creating these variables and setting their values.
04:09When I'm setting the float, I'm using the f; when I'm setting the double, I'm not.
04:13That's because when you write a literal, including the decimal point, it's always
04:18going to take it as a double unless you put the f after it.
04:22Now, in both of these cases I'm just using 7.2, which is a value that will fit in
04:27both a float and a double just fine.
04:29So it doesn't really matter, but the f is good practice.
04:37So in my code here I have a couple of lines that are creating that float and
04:41that double variable.
04:43What I want to show here is the slight difference when we have to write them out in a message.
04:47So if I do an NSLog and say "The value of myFloat is," well up to this point for
04:56our placeholders we've been using %i and then after the comma the name of the
05:03variable we're talking about.
05:04Now, if I run that, we're going to get some output,
05:08although it's going to kind of complain about it. The value of myFloat is 1.
05:13We're getting a bit of weirdness there. Why is that?
05:16Well, because we're saying we want to write out a float variable, but we've
05:20given an integer placeholder.
05:22So instead of %i here I'm going to say %f. Run that again and now we're getting
05:28The value of myFloat is 7.20000.
05:33By default using the %f will write out 6 places after the decimal point.
05:38However, we have an alternate way of writing this out which is using
05:42exponential notation.
05:43Instead of %f we use %e. Run that, and then we have the proper floating-point
05:51notation for our information here.
05:53Now, if I want to write out the contents of the other variable, because right now
05:57it's complaining that I'm not using the myDouble variable.
06:01So I'll copy and paste that message and say "The value of myDouble is." Now you'd
06:07be forgiven for thinking that if it was %i for integers, %f for floats, that it
06:13might be %d for double.
06:14But no, we actually use exactly the same placeholders for floats and doubles.
06:19So, %f for the decimal representation, %e for exponential and there is also %g,
06:27which will make its own guess as to which one will be the best to show.
06:30I like to be explicit here.
06:32So we'll run that one and we get exactly the same output in our debug area.
06:36Now, technically speaking you can use the long modifier in front of the word
06:41double, but it doesn't do anything in Objective-C so don't use it. Even Apple
06:46themselves will say that it's broken and don't do a long double in Objective-C.
06:51The last thing that I want to show here is just a bit of information about how
06:55floats, and doubles, and integers interact.
06:58Let's say that we start off with a couple of simple integer variables, say int a = 25.
07:04int b = 2.
07:07I'm now going to create a float.
07:10I'll call it result, and I'll set it equal to a / b. So 25 divided by 2, which would be
07:2012.5, and then after that I'll write out a message, "The result is %f," result.
07:32And I'll run this. Build succeeded and it's showing all of the messages.
07:37Here we can see "The result is 12.000000" etcetera.
07:40Well, what's going on?
07:44Well up here on line 18 where we are dividing a by b, that's being done as
07:50integer arithmetic, because both of the values in there are integers.
07:54What that means is it will truncate anything after the decimal point.
08:00It won't round it up.
08:00It won't round it down.
08:01It will just forget about it.
08:03That's worth bearing in mind when you're performing operations that involve integers.
08:08Now, what we have to do is we have to tell Objective-C well, hang on a second,
08:13I'd like to treat one of these, at least one of the pieces of this operation, as
08:18a float, so that I don't lose anything after the decimal point.
08:22What I can do with that is use what's called the cast operator.
08:25It sounds kinds of complex. It really isn't.
08:27It just means before either the a or b variable here, I need to open my
08:32parenthesis and write the word float.
08:35Basically means convert a into a float and then divide it by b and as long
08:39as one of these two pieces of this operation is considered to be a float,
08:44we run this again and we get the result being spit out down here at the bottom as 12.5.
08:49Just something to be aware of when you're working with integers and floats together.
08:54Now, to let you know, Apple themselves have written objects to deal with
08:59more complex numbers.
09:00So let's say for example you're dealing with currency a lot and a lot of large
09:06dollars and cents, or pounds and pennies values.
09:09Well, floats aren't really the way you want to do that, because that's
09:13floating point arithmetic.
09:14It's not exact decimal arithmetic.
09:17So there are some objects that exist in the frameworks that we can use to deal
09:22with larger numbers, something called NSDecimal number.
09:25But that's not where we are right now, we're working with integers, floats, and
09:28doubles, but we will get to those stuff a little later on in the course.
Collapse this transcript
Working with characters
00:00Wrapping up the primitive data types, we have the char data type to represent a
00:05single character, not a word, not a phrase, not a paragraph, but a single
00:10character and it uses single quotes, not double quotes.
00:13Chars can't hold more than one character because they're stored as one byte,
00:17one byte that can represent any character in the ASCII character sets. Not even Unicode.
00:23So this could represent b or an uppercase B. It could represent a special
00:26character, like an exclamation mark, or the digit 7.
00:31This would be 7 as a character, not 7 as a number.
00:35Now if you wanted to spit out a char variable in a format string like an NSLog
00:40message, well we have %i for integer, %f for float, we have %c for char, and
00:46that would work just fine.
00:47Not really much more to this one.
00:49It's not a very interesting data type by itself and you probably won't use an
00:53awful lot of them, but certainly something to be aware of.
00:56In Objective-C we also have a Boolean data type.
00:59We want to store a variable with a Boolean value, something that only has two
01:04possible states, usually referred to as true or false.
01:08Now unlike ints, floats, doubles and chars, there wasn't a BOOL data type back
01:16in C in the 80s when Objective-C was added to the C language.
01:20So the BOOL data type was added in the Objective-C pond.
01:24It's a little different from the others.
01:26Rather than write bool lowercase, like int and floats and char and double, we
01:31write BOOL, all uppercase, and unlike other languages were Boolean values are
01:36typically represented with the words true or false, in Objective-C we use YES
01:42or NO, all uppercase.
01:43No quotes around this, so no double quotes, no single quotes.
01:47YES, all uppercase is understood and as is NO.
01:51So it looks a little odd.
01:52Almost seems like you're shouting when you're defining these variables.
01:55But BOOLS are very simple to use, possibly the most simple data type there is.
02:00Two possible states, YES or NO, and even when you're using them in say an if
02:04statement, all we'd need to write is if (isCompleted) and that will either be
02:10YES or NO or true or false, the equivalent of.
02:13I don't even have to say if (isCompleted) = YES,. This would work just fine.
02:18It's very simple to use.
02:20Now just as an aside, kind of a little trivia point, you could in Objective-C
02:26write a BOOL variable using bool lowercase and set it equal to the words true or false.
02:35Now Xcode is throwing up a warning here but it's simply because I'm not using
02:39either of these variables.
02:41My question is well, why is this?
02:44Why would I use BOOL all uppercase and YES all uppercase when I could use bool
02:49and I could use true?
02:50While the bool data type, bool in lowercase, did not exist in C back in the 80s,
02:56they ended up baking bool into the C language about ten years ago with C 99.
03:02And because Objective-C is based on top of C, we kind of end up having two bool data types.
03:08But we are going to be using the one on line 15, BOOL all uppercase and YES and NO.
03:14And this is not because of tradition.
03:16It has nothing to do with that.
03:18It's simply down to the fact that because we have so much history with the
03:23BOOL data type as defined in Objective- C, there are hundreds and hundreds of
03:28classes out there that use BOOL all uppercase and they expect that definition of the data type.
03:34So while you could use the lowercase bool in your own code, it's going to make
03:38things very inconvenient for you trying to do interoperability with other parts
03:43of the frameworks that are available to you on Apple hardware.
03:47So we'll use BOOL all uppercase and YES or NO, all uppercase.
03:52Now if we wanted to write that one out in say a log message, so %i for integer,
03:57%f for float, %c for char.
04:00You would be forgiven for thinking it was %b for BOOL.
04:02But no, BOOL doesn't actually have a format specifier. Well internally a BOOL
04:07is actually represented with a signed char because it's the smallest datatype
04:11there is, only one byte.
04:13The best way to spit out the value of a BOOL would be %i for the integer value of it.
04:19We are not going to get the words YES or NO here. What we will get instead is
04:240 for NO, 0 for false and 1 for true or YES, however you want to think about it,
04:29which is typically the way these are represented in other programming languages as well.
04:34That wraps up the primitive types built in to Objective-C.
Collapse this transcript
Variable scope
00:00Sooner or later everyone new to a C-based language writes some code like I'm about to.
00:06I've got a simple for loop on line eight here that loops around 10 times,
00:11creates an integer inside it, writes out the value of that integer.
00:15But let's say I come along and after the loop has closed, I am going to write
00:19another NSLog message. The last of value all of foo was, give it the little
00:25placeholder, and then say I want to write out that variable that was created down on line 10.
00:32I save it, I build it.
00:33Build has failed. Use of undeclared identifier 'foo'. Did you mean for?
00:38No I didn't. I meant foo. I can see it.
00:40It's right there. It's on line 10, but I will not be allowed to write this out.
00:45This is because of something called variable scope.
00:48Every variable has a scope, a place where it's visible and accessible.
00:53By default, variables only exist inside the statement block they are defined in,
00:59in what are called local variables.
01:01So if a variable is created inside a for loop either inside the braces or as
01:06part of the initializer, say on line eight where we are creating the integer i,
01:11it only exists inside that for loop.
01:14Once we get one step beyond the closing curly brace, it has gone.
01:18If a variable is created inside the braces of an if statement, it only exists
01:23inside those braces.
01:24If it's defined in a function, the variable is only available inside that
01:29function and most of the time this is the behavior you want.
01:32So this line 14 is not going to work.
01:35Now do be aware that this is a restriction that only works from the inside out.
01:40What I mean by that is if I created a variable say here on line eight called
01:45integer x equal to 10, that variable exists and is accessible inside the main
01:52function and inside any for's or if's or while's or do-while's inside main.
01:59It's available all the way down.
02:02So inside this for loop, I can say x++.
02:05That would be perfectly acceptable.
02:07What I can't do is take foo and make it available outside of this internal for loop.
02:15Once again most of the time, this is the behavior that you want.
02:20I am going to get rid of those variables there.
02:22Now the question might be well, but what if I wanted to use the same variable
02:27between different functions?
02:29Well, that's perfectly accessible.
02:30Let's say I create just a simple function here.
02:33I'll call it myFunction.
02:34It takes an integer parameter that I'll call someValue and I'll just have a
02:42simple NSLog message that writes out whatever was passed in.
02:47Now, I can certainly come into my main function and even into the nested for
02:53loop and here on line 14, I am going to add a line that calls myFunction and I
02:58am going to pass in foo, which should be equal to 55. I run this.
03:03This should work absolutely just fine.
03:05We are just passing it in.
03:06We are calling that function 10 times.
03:09So we are getting all these different messages popped right back out there.
03:12However, bear in mind what's actually happening here.
03:16When we call the function on line 14, we're passing foo, but strictly speaking
03:23we're passing the value of foo.
03:25We are copying the value.
03:27So I declare foo on line 13, set it equal to 55, and then I pass it into the function.
03:32If in the function I accept it and I give it the name someValue and then I say
03:38someValue equals someValue plus 10.
03:44I'm changing the copy of foo.
03:47I'm not changing foo.
03:48Just to prove that, we'll run it 10 times and you'll see it be 65 passed into
03:54the function, but still 55 when we go right back outside again.
03:58So we are not truly sharing variables between functions; we are just copying
04:02them as we send them around.
04:04Well what if I actually really needed to share say a simple variable like an integer?
04:10Well, what I can do is define it as a global variable as opposed to the local
04:16variables we've been defining.
04:17To do this, what I simply do is I define it outside all of the functions
04:23available to all of them.
04:25So right up here outside the #import, but outside of main and outside of
04:30myFunction, I'm going to create a new integer variable.
04:34I'll call it int bar and I am going to set it equal to 10, which will be how
04:39it gets initialized.
04:40Now what I then find is that the bar variable is accessible inside myFunction.
04:46Now we can actually write it out.
04:48I am kind of ignoring my parameter, but that's okay.
04:59It's also accessible inside even multiple levels of nesting inside main.
05:05I'll say bar++ again and because bar is global, it can be affected by any of the
05:11functions at any level of nesting.
05:14I am going to save that and run that and we'll actually see that while foo
05:17remains the same, at 55 every time, bar is jumping up twice every loop because
05:23it's being added to once in the loop and once in the function call.
05:26So even here I can see it jump from 16 to 18 to 20 to 22 to 24 and so on.
05:32Now you'll usually find global variables referred to as kind of unnecessary evil.
05:37They are something to be avoided, simply because having a variable that
05:42can be changed from anywhere in your code can make them very difficult to debug,
05:46but we'll occasionally see them.
05:48Now the last thing I'm going to talk about here with variable scope is something
05:52that hopefully you won't run into too often, but it's just worth pointing out.
05:56So I am going to simplify this code again, back to the way it was a few minutes ago,
06:03where I have on line nine an integer variable called foo being declared.
06:07What I am going to do is outside the for loop I am going to create an integer variable.
06:13I am going to call it foo, set it equal to 10, save that, build it, saying the
06:21build has succeeded.
06:23I have two lines that are identical now, line 7 and line 11.
06:29I think that's okay, but say if I'd done it again, if I have integer foo
06:33equals 11 and I declare it again right next to this, it's actually going to complain about it.
06:39It will say no, you are redefining it. That's not allowed.
06:42But it seems to be allowed inside the for loop and it is.
06:46The fact that variable scope can change from block to block allows you to
06:50redefine variables inside statement blocks and you see what I could do now is
06:56on line 15 I could uncomment the line that was giving me a problem a few
07:01minutes ago and this build actually succeeds.
07:04The question is well, what value will I be writing out?
07:08If I'm trying to write out the valley of foo on line 12 and I am trying to write
07:12it out on line 15, which one am I using?
07:15Well the rule is whatever is closest wins.
07:19So if I run this, we are going to go through that loop 10 times and we'll be
07:23writing out 55, which was the definition of foo within the loop.
07:28Once we're back out of the loop as, this last message, we'll write out the last
07:32value of foo, which was 10, how it was declared on line seven.
07:37So when I redefine the variable foo on line 11 that takes over and this becomes
07:43the accessible one inside the statement block and inside any statement blocks
07:48that were nested inside this one.
07:50So be careful with this one.
07:51It's certainly not a best practice to redefine variables, but as you see the
07:55compiler won't complain about it if you do that.
07:58That can easily lead to confusion between yourself and others as to what the
08:02right scope is for that particular variable.
Collapse this transcript
Enumerations
00:00You know sometimes we just have too many choices.
00:03Let's say I'm creating a variable called bobSeatPreference.
00:07If I define it as an integer, this could have a range of 4.3 billion different
00:12values, but I wanted to represent a preference of Window, Middle, or Aisle.
00:17Well, there is nothing that would of course stop me.
00:19I could just say 1.
00:21That's perfectly acceptable and just have it in my own head that in this program 1 means Aisle.
00:28I could even say myself a little bit of space and put short int, but I have
00:32still got 65,000 different values and there is nothing that actually stops me
00:36in the code setting it equal to 123, which would be out there on the wing somewhere.
00:41So wouldn't it great if there is a way of defining some kind of data type with a
00:45much more restricted range of possible values?
00:48And I'm sure you're right there with me, that yes there is indeed. It's called
00:52an Enumerated data type or an Enum for short.
00:56What we'll do first is define those range of values.
01:00We use the word enum and then describe whatever it is we're wanting to define.
01:04In this case, I'm saying seatPreference just in general.
01:07I'm not creating a variable here, so there is no equal sign and I just use the
01:12opening curly brace and closing curly brace and inside those braces I list my
01:17values that I want this to be, and you can use your own words here.
01:21So I can to say window, aisle, middle.
01:26It's up to me. If I wanted to have something else that meant no preference or what have you,
01:32it's completely my decision. Those words and how they are spelt they are up to me.
01:36What that means after we're done is we can use the phrase enum seatPreference
01:41as a data type. Instead of creating a short int or an int for bobSeatPreference
01:46I type in enum seatPreference, then the name of the variable, and instead of = 1,
01:51I'd say = aisle.
01:52I will create another variable of that same type, but this one is for
01:57fredSeatPreference and he wants window.
02:01I'm allowed to use those words.
02:03It will restrict me to those possible values.
02:07If I say the Joan's one equals to front and compile that, I'm going to get to
02:12no, there is a problem.
02:13I did not assign one of the listed values for the enum.
02:18And the benefit is that later on in the code what I can do is ask a question,
02:22like if bobSeatPreference == window, then go and do something.
02:30Without having to remember now, did one mean window or was it two windows
02:34or was it zero window?
02:35You'll find that these are used quite a bit inside of the Foundation framework.
02:38It's just a way of restricting ranges of values in certain classes and
02:43they're really good for that.
02:44Now if we write them out in say a log message, all we have to realize is well,
02:50how do we describe this, how do we write out an enum?
02:53Well, technically you see an enum is actually stored internally as an integer.
02:59So we can use the %i to write one out.
03:03The question is what's it going to do?
03:05Well, unless you tell it otherwise, the enum is actually going to pick the first
03:09value as zero, the second one as 1, the third one as 2, and so on.
03:14If you had other numbers you wanted them to represent, you could do so.
03:20I'm picking numbers here that don't really have much drastically important to them.
03:24So when I run this program, fredSeatPreference, which was assigned to window,
03:28should be popping out in the message as the number 99, because that's how it's
03:31internally stored in the enumeration.
Collapse this transcript
Using typedef
00:00When we create an enum, it almost sort of kind of feels like we're defining our
00:05own data type, even if it feels little clunky to do it.
00:08Now we can take it one step further and actually really define our data type.
00:11There is a word called typedef. What that allows you to do is assign a new name
00:18to an existing data type.
00:20Something as simple as this is perfectly acceptable.
00:22I can say typedef int and then give it a new name.
00:25I'll call it simonsInt.
00:26I think well, what does that do?
00:28Well, we can now create variables of that type, and in this case they'll behave
00:36exactly like the underlying type of an integer.
00:38Now there's no real point in just redefining an integer right now but we
00:42could do it that way.
00:44What is quite common, however, is there is something that's a bit more complex
00:47to define such as the enum could be redefined with a typedef and then it makes
00:53it easier to create variables of that type instead of saying enum
00:56seatPreference all the time.
00:57So how do we do it?
00:58Well, what I'm going to do in this case is use the word typedef, then what we do
01:03is describe the type and then what we do is say what the name is.
01:07Well, the name that I wanted was seatPreference.
01:11So I'm going to cut that part out of the lower line where I declared in line and
01:15just paste it in up here.
01:17And then the rest of the definition is the enum, which is the type.
01:21So it's almost like kind of reversing things a little bit.
01:24So on line five, I have now defined a new type called seatPreference that is an
01:31enum with these three settings:
01:33window, aisle, and middle.
01:34And the reason why it is complaining about on line 10 and 11 is I don't need enum anymore.
01:39I can literally just create variables of type seatPreference.
01:44Now commonly, you'll find this defined outside a block like main, because it
01:52will need to be available not only in the main function but also anywhere
01:57else in the project.
01:58That's perfectly acceptable because this line of code does not actually do anything.
02:02It doesn't cause anything to happen except it describes this new type.
02:07And you'll find it mostly used to just shorten some code to redefined types that
02:12like an enum would be quite clunky to keep on writing otherwise.
Collapse this transcript
Preprocessor directives
00:00In every project that you create in Xcode, you're going to see lines that look
00:04something like line 9 here, the import statement that begins with the pound
00:08symbol or hash symbol if you prefer.
00:10This is not a line of Objective-C, which is why it doesn't need a semicolon.
00:14It is instead what's called a preprocessor directive, and that simply means it
00:19causes something simple to happen before our code is compiled.
00:24You see anytime you hit Command+B or you select Build from the Product menu or
00:28you try and run the program, all these files are scanned, all the files in
00:32your project, for these preprocessor directives, these instructions that begin
00:37with this # symbol.
00:38And if it finds any, it causes something very simple to happen.
00:42In the case of the #import, it simply means go and find this file called
00:46Foundation.h and whatever it includes paste it in here.
00:50It's a way of including the content of a separate file in this one.
00:54If Foundation.h had its own #import statements, it would go and find those files
00:59too and paste all the results into our own file. It becomes part of our own code.
01:04But there are a couple others worth knowing about.
01:08#define, this allows us to create what's called a macro.
01:11It's really just a little shortcut, commonly used to do something like this, to
01:15create a value and give it a name.
01:18It might sound like a variable, but this is really very different.
01:22In this case, I've defined something called HIGHSCORE=1000000.
01:24These are usually written in all caps. They don't have to be but it makes
01:28them very recognizable.
01:30I don't use an equal sign. I don't use a semicolon.
01:33Now HIGHSCORE is not a variable.
01:35It's not changeable.
01:37But what I can do from this point on is anywhere in my code I create say a new
01:41integer called a and set it equal to whatever HIGHSCORE is plus 500.
01:47I can write out the contents.
01:52I can change variables that are based on that value.
01:55What I can't do is change the value.
01:58You'll commonly see it being used to declare things that really need to be fixed
02:02values like let's define PI as 3.14159265, and then we could use the word PI
02:09anywhere in our code. In the same way that the #import statement just does
02:13something very simple by finding the file and coping its contents.
02:16And here all that the #define does is the equivalent of a find and replace.
02:21It's basically taking the value and before our code is compiled saying hang on
02:26a second, just going to go through your code, find that word, and then replace
02:30it with that value.
02:31That's the end result of the #define.
02:34The benefit of course is what we can do is then declare a lot of these
02:39#defines up at the top and it gives us one place to change these values if we
02:43need to change them.
02:44Now what you'll find is you're probably a bit more likely to use other built-in
02:48macros than to define your own.
02:50I'll give you an example.
02:51Here I'm going to write out an NSLog message that says the maximum value of an
02:56int is integer placeholder and then what? Well there is actually a built-in one.
03:04When I'm going to start to type INT, I've INT_MAX, INT_MIN, and I'll do INT_MAX.
03:12This is a built-in predefined macro that's actually in some of the underlying C Libraries.
03:19That's just been defined with that number, so we don't have to bother
03:22about remembering it.
03:23I'm going to run this and it not surprisingly outputs a message here.
03:27The maximum value of an int is 2147000000 and so on.
03:32There are a lot of these, you've got-- if I start typing FL-- you've got Float
03:37Max, Float Max 10 Exponents.
03:40There is a lot of stuff.
03:41Why they're written in caps is they make it quite easy to recognize,
03:44although you'll see the hash mark or the pound symbol at the start of them
03:47when you're looking them up.
03:50Back to INT_MAX there.
03:52The last one that I'm going to talk about in terms of preprocessor directives
03:55is the if statement.
03:57Now we have an if statement in Objective-C and we're certainly going to get to that.
04:01But this one is a really easy one allows us to have conditional code and that
04:07might sound little strange.
04:08So let me be sure what I'm talking about here.
04:11What I'm going to do here is type if DEBUG, endif.
04:14Now bearing in mind that any and all of these preprocessor directives cause
04:21something to happen before our code is executed.
04:24And what this is going to do is scan through our code.
04:28It hits line 16, and it's going to ask, are we compiling in Debug mode?
04:34If we are, then that's fine. I'll leave this line of code in.
04:38If we're not, I'm just going to pull this code out.
04:41This is a very different idea from when we're running our program is it going to ask anything.
04:45This is happening before we compile and our code will actually be stripped out,
04:50as if we've never written it at all.
04:52So how do I change this?
04:53Well, if I go up here into my Scheme dropdown, what can happen is I can edit
04:59the settings of this and I can change from a Debug configuration to a
05:04Release configuration.
05:05Now let me leave it at Debug and run it.
05:10I get that little diagnostic message about the maximum value of an int.
05:14If I go and switch it, change to Release, click OK, run it again, I don't get
05:21that message at all. It was as if it was never written in the program.
05:24Now the way that quite a lot of developers use this capability is to be able to
05:29put in say quite a few diagnostic messages that's peppered throughout the code.
05:34Then rather than have to go and rip all that code out when they're actually
05:37compiling it for release, they just make it conditional using these preprocessor
05:41directives and it's as if that code never existed in the first place.
05:45Those are the three most common preprocessor directives that you're likely to
05:49run into either writing them yourself in Objective-C or by reading through
05:53the Apple sample code.
Collapse this transcript
Working with strings
00:00Let's finally get around to strings in Objective-C.
00:03How do we work with text, words, and phrases and sentences?
00:08Now depending on which language you are coming from, you might expect to be able
00:11to write something like this, just string message = "Hello".
00:17But no, this is not going to work.
00:19In fact this is not going to work in several different ways.
00:21There is no built-in string type in the Objective-C language and again this goes
00:27back to its roots in C where you manage strings as arrays of characters,
00:32and those are pretty tedious to deal with.
00:34So we don't want to work with the C style character arrays and we don't have to.
00:39Instead, we use the NSString type to work with strings and we do it like this.
00:45Now looks a little different, so let me go through this.
00:48The first part is the type. It is NSString.
00:52Now while NSString is not officially part of the Objective-C language, it might as well be.
00:58NSString is part on the Foundation framework, a collection of different
01:03pre-written pieces of code that we are linking to.
01:06That's what this #import statement does that we have in pretty much every
01:11project that we will ever write in Objective-C.
01:14This import of Foundation/ Foundation.h is pointing to the
01:19Foundation framework.
01:20In fact, if I look at my Project files and expand Frameworks, I'll expand the
01:26Foundation.framework here, and I see a whole bunch of stuff, most of which
01:31begins with NS, NSBundle, NSCoder, NSDate, NSDecimal, NSDistantObject, NSPort,
01:39NSObject and NSString.
01:42Now, I don't want to ever have to change this.
01:44It looks fairly intimidating here.
01:46But this is what that #import statement does, is it links to all that extra code
01:53so that we will have a string data type to work with, NSString.
01:57As I mentioned before, the NS comes from the old Next Step days and while it
02:03might seem a little strange to have a 15-year-old operating system
02:06determining your strings and your dates and your reports and your paths that
02:11you write in Objective-C,
02:12well you just got to have to get used to it because it's not going away.
02:16It's written with an uppercase N an uppercase S and another uppercase S. Again
02:20case-sensitive and again, use Code Sense code completion to help you in those
02:25early days while you are still getting used to it.
02:28So the last part, the value over here which looks a little strange.
02:32We've got the double quotes which represent a string but we've got the @ in front of it and
02:38we've seen this before in all our NSLog messages. We are using that @.
02:42Well what's this all about?
02:44Well the @ is a clue to the compiler.
02:47And it's not like this is the only one we've used.
02:50If we say create float variables, we use that little f to say hey,
02:54this is a float variable.
02:56If we are using a character, we use the quotes. We are making an indication to
03:01the compiler, this is a float, this is a char.
03:04Well, what we're doing with that @ is we are saying this is an NSString.
03:09If we left the @ off, and that's a very common error for people to make,
03:12that will be considered a C style character array and it's not going to work very well.
03:17So we have got two pieces here, then in the middle we have the name of the
03:22variable, which in this case is message, but what's this other piece, what's this asterisk?
03:27Well, this asterisk means pointer and what this means is that the variable
03:33message that we're creating does not directly hold an NSString.
03:37it holds a pointer to an NSString object.
03:41It points to a different area of memory where the contents of the string are stored.
03:46Well, there is a lot of reasons for this.
03:48The reason why we're hitting this now is that we are finally moving from classic
03:52C in its float char into real Objective-C.
03:57This is the first code we have written that creates an object. But we are in an
04:01object-oriented language and we will make a lot of objects.
04:04And in Objective-C, all objects are accessed using pointers.
04:09We will be using this asterisk every single time that we write code to create an object.
04:16And if you look at line 6, the NSAutoreleasePool line that's being generated,
04:21the asterisk here means pointer as well because this is an object that is being created.
04:28pool is a pointer to an NSAutoreleasePool.
04:32You can put the asterisk anywhere.
04:35It is very commonly written like this where the asterisk is right by the
04:39variable name. The asterisk is not part of the variable name.
04:43I am not making a variable called *message.
04:47I am making a variable called message and it is a pointer to an NSString.
04:52So I could write it with the asterisk against the word message, I could write
04:56it with a space in between both of them, I could actually put the pointer right by NSString.
05:03All of this would work and you are actually likely to see it done all different ways.
05:08Different people have different preferences.
05:09Now one of the questions is, do I always need it? And yes you do, when you are
05:15creating these objects, but let me show you an example here.
05:20So on line 11 here, I am going to define a variable called message.
05:25It is a pointer to an NSString.
05:27If you would prefer, you can put a space in-between.
05:30again it is not whitespace sensitive.
05:31You could put the multiple spaces in between but message is a pointer to an
05:35NSString and the contents of message will be @"hello".
05:41Now, it's given me a warning right now because I am not using it, so I might as well use it.
05:46Let's write an NSLog, "The value of a message is... Well how are we going
05:53to write this one out?
05:54It is not going to be %i. it is not an integer or %f. it is not a float.
05:59It is not a character either.
06:01The way we are going to write this out is we are going to use %@ and this
06:07is not for strings particularly.
06:11%@ is the placeholder for objects.
06:14A string is an object. So if the %@ is my placeholder, then I will write a
06:19message and notice that I'm not using *message.
06:22Again, the name of the variable is message.
06:24I save that, I run it and we should get the message out here that the value
06:29of message is Hello.
06:31No particular surprise there.
06:33The thing that I was going to show is where exactly is the asterisk needed?
06:38Well, it is typically there when you are defining what this variable is.
06:42So let's say I wanted to split this into two pieces.
06:47First line, declare a variable called message.
06:50It's a pointer to an NSString.
06:52Next line, I want to set it.
06:56Now, what occasionally puzzles people is why didn't I need an asterisk at
07:05the start of line 12?
07:07Well, I don't, because I've already told the compiler what message is.
07:11It is really the same as on line 89.
07:14If I declare an integer called foo, then on line 9 when I am setting foo,
07:18I don't need to tell it again that it's an integer.
07:20It already knows that it is an integer.
07:22On line 12, I don't need to say that it as a pointer to an NSString.
07:25It already knows that.
07:26I just used the variable name.
07:29Now everybody gets a little puzzled by pointers the first time they deal with them.
07:33If they don't seem intuitive that's okay, you're not alone. Pointers have been
07:38confusing people for decades.
07:42Now we are going to get much deeper into this, but understanding that an
07:45NSString is an object leads us into, well, what exactly does it mean to be an object.
Collapse this transcript
5. Classes
Introduction to object orientation
00:00Beyond the syntax changes the @ signs and the square brackets, the real
00:05difference between regular classic C and Objective C is that regular C is a
00:10procedural programming language and Objective-C is an object-oriented program language.
00:15Well, in a procedural programming language like C, the program is written as a long procedure.
00:21Even though it might be split up into files and functions to make a more modular
00:25maintainable, it's really effectively a long piece of code combining data and
00:30logic all mixed in together.
00:32But in an object-oriented programming language this program would instead
00:36be split apart into self-contained objects, almost like having several mini
00:40programs each object representing a different part of the application, each
00:44object contains its own data and its own logic and they communicate between themselves.
00:50Now you can't avoid object orientation in Objective-C.
00:54You can'y even write the simplest Objective-C program without using it.
00:58And while object-oriented programming can bring a lot of jargon to the
01:02table, there are really only a couple of terms we need to be comfortable with to forward.
01:07The first and the core idea is the idea of a class and an object.
01:12These two things go hand in hand.
01:14A class is a blueprint an idea, a description, a definition.
01:19It describes something, but it isn't the thing itself.
01:24Like a blueprint describes a house, but it isn't the house.
01:27It is a well-defined idea.
01:29The classes will exist for many parts of your applications.
01:33Some classes you may write yourself, say you are writing a restaurant review
01:37application, you might have a class to represent a restaurant, another one to
01:40represent a review, a class to represent a user of your app.
01:44These classes would all describe them very well.
01:47There're also classes to represent visual parts of an application.
01:51If you are building a desktop or an iPhone app, there are existing classes that
01:55represent text boxes, buttons and windows and menus, but classes can also
02:01represent more invisible intangible things like dates and time zones.
02:07So you'll not only write your own classes, but you will also use many that
02:12Apple have already written in fact, everything you see here with the prefix and
02:15it does already exist in the Apple frameworks, but whether you're writing them
02:20or whether Apple write them, all classes describe two things, attributes and behavior.
02:27What are some things characteristics its attributes and what is its
02:31behavior, what can it do?
02:33So if we are describing a class to represent a person, we might say that the
02:37attributes of that person or a name, a person has a height and a weight and a
02:41gender and an age and then there's the behavior that it describes what can they
02:47do while a person can walk and run and jump and speaking and sleep and defining
02:53this is the key when you're creating your own classes.
02:57Now these two pieces can also be described with other names.
03:01When we start referring to object-oriented programming jargon you will often
03:06hear I am referred to as properties and methods.
03:09Properties of a class describing the class's characteristics, its
03:12attributes, and method's describing what it can do, but the class described
03:17everything in abstract.
03:18We say that something has a name, but we don't say what the name is because the
03:22class is the description and the object is the thing.
03:27So if the class was the blueprint the object would be the house.
03:32The object is created from the class.
03:35So obviously there is a sequence here, first the class is defined, and then the
03:38object or objects are created based on that class because you can take the same
03:44class and make multiple objects from it, in the same way you could take one
03:48blueprint and make multiple houses from it.
03:51In more of a programming context, we could have a class that represents a button
03:56and a desktop or an iPhone application and by creating multiple objects based on
04:03my class with different characteristics, we can have different buttons with
04:07different heights and widths and colors all based on that same core idea.
04:12Now if you've already been exposed to object oriented programming you know that
04:16there's quite a lot of jargon that comes along with it and one of the most
04:19common things you'll hear of the four keywords that can be used with remember
04:24about the phrase APIE, abstraction, polymorphism, inheritance, encapsulation.
04:29Well, right now we don't have to care about two of them, but it's worthwhile
04:33paying attention to the A and the E, the abstraction and the encapsulation ideas
04:39because that will help us build and use classes.
04:42Abstraction, that's simply the idea of focusing on the core pieces of something
04:48to describe it well, of reducing details to focus on the core concepts.
04:54It's what allows us to take the idea of multiple people and abstract out the
04:59idea of a Persian class what are the things that everything has in common.
05:05In our code it means that we create classes that focus only on those core pieces
05:11of information and the core capabilities of that class needs to have.
05:14And not only that, but that's what we should expect of the classes that Apple
05:20have already written that we want to use.
05:22Now hand in hand with this is the idea of encapsulation that we are taking the
05:26code that represents our properties, we're taking the code that represents our
05:29methods and we are wrapping it up, we are boxing it up in this class,
05:35encapsulated, sometimes referred to with the concept of black boxing and what
05:39keeping the functionality self- contained and that we will only share with other
05:43objects what we decide to share.
05:45By default everything is closed off and self-contained inside our objects.
05:49But what does that really mean for us?
05:51Well, an example, so, we can think of the class in essence as a type.
05:57We are defining say a new and a string object.
06:01Well what's happening here is the word and NSString is representing the class
06:05that already has defined when the object itself is being created on the
06:09right-hand side of the equals sign here and the variable message represents it
06:14pointed to that object.
06:16Now because we can create multiple objects based on the same class, we could
06:20have another line of text to create another object based on the same class and
06:25when objects are created, you'll often hear this referred to as instantiation,
06:29in fact the word instance and object are really interchangeable.
06:33Object is an instance of a class.
06:36Now when we are working with the NSString, this is a bit of a lazy way to do it
06:40because we're having the object being created very simply by using the at sign
06:45and the double quotes.
06:46In more typical environment, the actual process of creating an object is a
06:50little bit more complex and you've actually seen it already.
06:54The first line of any main method that we have has this line NSAutoreleasepool
06:58and what's happening here is really we're going through the same process.
07:03The class is NSAutoreleasepool.
07:06We have a pointer to an object and we'll talk about pointers in a minute and
07:10on the right-hand side of the equals sign we'll have the object creation process itself.
07:15But in the very first line of this simplest project that you have, that you
07:19have this line of code we're using class as we're creating objects, we're having pointers.
07:25You can get away from this object-oriented programming idea, but at least some of
07:29the basic concepts allow us now to drill down and explore what's exactly
07:33happening on this line here.
Collapse this transcript
Using objects and pointers
00:00I have said it before and no doubt I'll say it again.
00:03In Objective-C all objects are accessed using pointers, all objects are
00:08accessed using pointers.
00:10If you want to make and use an object even from a simple class like NSString,
00:16you will need a pointer to reference that object.
00:19So, we will be using this asterisk every single time that we write codes
00:24to create an object.
00:25Now, here is the key difference between needing one and not needing one.
00:29You see when you create an integer variable, we are writing a line of code like
00:34this, what's going to happen an area of memory.
00:37in this case, 4 bytes will be allocated for that variable and it will hold
00:41the value directly.
00:42Well, in this case, the binary representation of 100, but the variable holds
00:48the value directly.
00:49However, if you write a line of code to create any object, a variable is
00:55still claimed in memory.
00:57in this case it is called message but it does not hold the object itself.
01:01Instead, it holds an address, a reference, a pointer that points to a different
01:08area of memory where that object itself exists.
01:11Now, I am often asked the question, why are objects handled differently?
01:15Well, there are few reasons but the most basic is that objects are more complex
01:19than primitive types.
01:21We know how much memory to reserve for a char, 1 byte.
01:23We know how much memory to reserve for an integer. 4 bytes.
01:26But how big is an NSString?
01:28How big is a piece of video?
01:29How big is an image?
01:30We don't know, and it might even change during our program and while it is
01:34running, we need a more flexible way to manage objects and pointers allows us to
01:39do that and having a pointer, just an address allows us to pass the object
01:43around without coughing and which could be time-consuming and inefficient.
01:46We just passed the address of the object around and we passed the pointer.
01:50Now, you may wonder, do I actually need to know what the address is, what that
01:55pointer value is, what that address of memory is.
01:57Well, no you don't.
01:58It doesn't matter, but you do need to know that's what's happening.
02:02Now this is the way that most object oriented languages work under the hood.
02:06Even languages like Java and C# work this way.
02:08They just hide the asterisk away.
02:10Now, when declaring again, we can put the asterisk anyway.
02:14You will commonly see it written like this, but you could have a space between
02:19the class name, and the variable name or you could have the asterisk right up
02:23against the class name itself, because the asterisk is not part of the
02:28variable name here.
02:29We are not trying to make a variable called *message.
02:31We are making a variable called message and it's a pointer to an NSString object.
02:37We can think of the asterisk representing the word pointer here.
02:41Now two common misconceptions, I am going to go through.
02:44Common misconception number one.
02:45do I always need and the asterisk with that variable? No you don't.
02:49Let's say I wanted to define this variable called message.
02:53It's a pointer to an NSString and I want to set its value.
02:56Well, I can just use the variable name message = @ "Hello".
03:01I don't need to use the asterisk on the second line here because Objective-C
03:04already knows that message is a pointer to an NSString.
03:08As an equivalent, if you were declaring say an integer called foo and then you
03:12wanted to write a line of code that says foo = 45.
03:15you don't need to say that foo is an integer again.
03:18Objective-C already knows and that's the equivalent with message.
03:22Objective-C already knows message is a pointer to an NSString.
03:26So you use the asterisk when you are telling Objective-C what something is.
03:32not what its value is, but what its identity is.
03:35In this case, on line 15, I'm saying that message is a pointer to an NSString.
03:41We also have the code on line 13 that is saying, pool is a pointer to an
03:46NSAutorelease pool object.
03:49Now both of these objects are being created slightly differently here, but
03:52that doesn't matter.
03:53That's not what we are interested in right now.
03:55So the pointer symbol is used when you define the object and the second place is
03:59going to be used is when you start to pass it around.
04:02Let's say I want to define a new function, and I want this function to accept a
04:07parameter in here that will be an NSString object.
04:11I have got to think, what am I actually expecting in here?
04:14Well, if I was expecting an integer, I would give it a type which would be say
04:18integer a. That would be fine, but if I want to pass an NSString object, I got
04:24to think, what am I passing?
04:25Well, I wouldn't be passing the object itself.
04:28All objects are pointer types.
04:30So instead, I would say NSString pointer, and then give it a name.
04:35In this case, let's call it foo.
04:37Inside the body of the function, I could then simply use that variable.
04:42And then in my main method, I am going to just call that simple function passing
04:47in the pointer to the NSString object.
04:50It is a wholly unexciting piece of code that we have here.
04:54But not surprisingly, we get that being output on our debug area.
05:01So in this particular example, I am using that pointer asterisk in three
05:07places that I can see it.
05:09One is on line 17, when the NSAutorelease pool object is being created.
05:14nothing to do with me.
05:15That's part of the template. Two.
05:17on line 19 when I define this NSString pointer object called message and three,
05:23when I define the signature of the function here and say I am expecting a
05:29pointer to an NSString as a parameter.
05:31But the other places that I am actually using it.
05:33on line 12 and on line 20 I do not need the *.
05:38The common misconception number two.
05:40doesn't it get confusing that the asterisk is used for pointers and also
05:43used for multiplication.
05:45No, it really doesn't.
05:46They are so different and used in very different context.
05:49As an equivalent for example, we are familiar with using the / for a division operator.
05:54But if you see a URL path, you don't suddenly think, well, this means
05:58www.lynda.com divided by news.
06:01It is a completely different context.
06:03In the same way, as you become familiar with looking at it, you will realize
06:07that when you see an operation like this where the asterisk is being used on
06:11the right hand side of the assignment operator, this is doing multiplication,
06:16whereas if you see an operation like this where the asterisk is being used on
06:20the left hand side after a class name, you will realize this is just a pointer declaration.
06:26Now if you are new to pointers, yes just realize they are not going to feel
06:30comfortable until you make a bunch of them, create them and use them and we are
06:35going to do that a lot in this course.
Collapse this transcript
Messages and methods
00:00Modular, reusable code. it's a good thing.
00:03Now we know that we can take a block of code, wrap it up, give it its own name
00:07and it is considered a function.
00:09But this is the old-school classic C way of doing things and we are
00:13in Objective-C now.
00:14most of the code that we are going to write or use will be gathered
00:18together inside classes.
00:20And if you took that same code, you wrapped it up, gave it a name and put it in
00:24a class it would be considered a method.
00:27A method it is basically a function that belongs to a class.
00:30It is how you describe, what it is that that class and any objects of that class can do.
00:36Let me give you a couple of examples.
00:38If I were to show you some of the classes that exist in the Cocoa framework,
00:42classes we can just use because Apple have written them already that might
00:46include say the AVAudioPlayer.
00:49This is an existing class that has methods like play and pause and stop and the
00:54kind of things you can probably guess an audio player would have.
00:57But even NSString has plenty of methods. It has dozens.
01:01We have an NSString object, we have methods like lowercase string, and
01:06uppercase string, length and has prefix and has suffix, we can do all sorts of
01:11things with that string object.
01:12When it comes time to write your own classes let's say we wrote a bank account
01:16class, we would be writing methods like deposit and withdraw and open and close.
01:21So it is how you describe what it is that that class can do.
01:25Now that's common object oriented stuff, but the question is well, how do we
01:29call methods in Objective-C because that's a little different than most other languages.
01:34In a lot of languages, you would call a method by using something called dot syntax.
01:40You would use the name of the object, dot, the name of the method, and then any
01:44parentheses that would say does this take any arguments in.
01:49This is not going to work in Objective-C.
01:52We don't use dot syntax in Objective-C to call methods.
01:55We use square brackets.
01:57Square brackets is one of those indicators to the compiler that this is Objective-C.
02:03So we are sending a message here, is the term that's actually being used and in
02:07fact the official term is that we are sending a message someMethod to the object myObject.
02:12It is all enclosed in the square brackets and there's no dot between the object
02:17name and the method name.
02:19Now some developers get really weirded out by the square brackets. It is just syntax.
02:23It is just a slight change, the concept is the same.
02:26But let's take it, a little step further.
02:28What happens if this method returns a value?
02:31Well, if you are familiar with dot syntax, you would expect to write some code like this.
02:36You would have a receiving variable and set it equal to whatever came back from
02:40myObject.someMethod ().
02:42Well it is exactly the same in Objective-C, you just replace the dot syntax with
02:46the square brackets and call it that way, but if the method returns a value,
02:50this would work just fine.
02:52Moving on one more step, what happens, if you want to pass an argument into
02:57that method so the method has been defined with parameters, we are passing arguments into it.
03:01Well, in dot syntax you would simply put the argument in the parentheses.
03:07The concept is the same in Objective-C, but instead of parentheses, we use a colon.
03:11So it is object name method name:argument, all within the square brackets.
03:18But that's how we pass in an argument to that method.
03:21Now where it gets a little bit more complex, is if we have multiple arguments
03:25because that is the first thing where it's really different and giving the
03:29analogy again of a dot syntax way of doing it you just pass in multiple
03:34arguments separated by commas.
03:36That's not going to work in Objective-C.
03:38The big difference in Objective-C is if you have a method name that takes
03:43multiple arguments the method name becomes split apart into multiple pieces.
03:48the actual name of the method changes.
03:51So let me show you an example.
03:54This is a real method that's available to you in Objective-C.
03:59It is the method insert string at index.
04:03More specifically it is read as, insertString:atIndex
04:06and the way we would write it, is use the object name, the first part of
04:11the method name which is insertString:
04:13and the first parameter space the second part of the method name which is atIndex:
04:19and the second parameter.
04:21So the actual method name is different, each parameter is named.
04:25Now if you have detected, I am using the terms parameter and argument kind
04:29of interchangeably.
04:30Officially, they're described as such, you pass an argument into a method which
04:35is received as a parameter.
04:37But you can kind of think about them the same way.
04:39Now what this leads to is something that Objective-C is notorious for,
04:43particularly, when people are new to it which is method names that are really,
04:47really, really long because if you think about it this way any method name
04:51that's been defined to accept multiple arguments is going to have multiple
04:56pieces to it and that leads us to -- I will show you a couple of my favorites.
05:00Let's say the NSFileManager has a method called replaceItemAtURL: withItemAtURL:
05:06backupItemName: options:
05:08resultingItemURL: error:
05:11Doesn't exactly roll off the tongue or perhaps even better than that one, in the
05:15built-in NSBitmapImageRep, we have -- well, I am not going to read this but you
05:20can see it is a fairly long method name.
05:22Now the big benefit of doing it this way is even though it gives you a lot more
05:26code to read and as you could you can split it across multiple lines, it becomes
05:31more readable in an actual program because instead of a smaller method call,
05:36where you are just passing multiple parameters and you don't really know what
05:40those parameters are, there are all meant here.
05:42It's obvious what they are and that's why Objective-C has the really long method names.
05:47And most of the developers I know that have spent some time with
05:50Objective-C actually begin to prefer it this way because it does make for
05:54more readable maintainable code.
05:55Now lastly, I am going to talk about here is nested method calls, just as in dot
06:00syntax that you could pass in a argument into a method or you could actually
06:06just nest in another call to a different function or method, you can do the same
06:10thing in Objective-C.
06:12instead of the standard Objective-C where I have been using the in the
06:15argument, we can add another set of square brackets and nest inside it another method call.
06:21The interior one will be evaluated first and the result of that will be fed
06:26into the exterior one.
06:28I don't tend to go any deeper than two levels though you can, but these will be
06:32passed just the way you would expect them to be passed.
06:35So that gives us the way of calling methods in Objective-C and let's go and step
06:41on a little further and we will actually see what methods are available to us.
Collapse this transcript
Using existing classes in the foundation framework
00:00Sure, you're going to write your own classes, but you're likely to spend way
00:04more time writing code that users wants that already exist.
00:08One of the challenges when you're new to Xcode and to Objective-C is finding the
00:12right ones, finding the classes, finding the methods.
00:15Let's take a look at how.
00:16I am going to make a new Xcode project.
00:17Once again, it will simply be a Mac OS X Application and a Command Line tool.
00:23I'll call this one ExistingClasses, and make sure to have a type of Foundation,
00:28not Core Foundation, but Foundation.
00:31The whole reason for selecting Foundation is so that our project is already
00:36linked to the Foundation.framework.
00:38That simply means link our code to a whole bunch of prewritten code that
00:44includes very basic datatypes, things like, NSString, NSDate, NSCalendar that
00:50I'm likely to want to use in pretty much every single project I'll ever write.
00:54So if I open up my ExistingClasses, I'm going to jump into the main file here.
01:00Now we've already worked with NSStrings, but if I hadn't done anything with it,
01:05how am I going to find information about this?
01:08Well, we've already seen that we do have the code sense, this automatic code
01:13completion here that as I start to type, it's going to help me do this.
01:17This is a good thing, particularly if you don't remember the case sensitivity,
01:21because it doesn't matter here.
01:22So I am going to type in NSString and just create something super simple here.
01:29Not really interested in the contents, more in the NSString itself.
01:33So if I wanted to find out what was available to me, I have a couple
01:36of different options.
01:37One is, if I had the Utility section open on the right and I can just toggle
01:42this on and off with this button up here on the top right, I have these two
01:46sections on the top.
01:47But if I select the one with the wavy lines, that's Quick Help.
01:50What that means is if I have my cursor selected in NSString, Quick Help will
01:55show me introductory paragraph, point me to the NSString class references, point
02:01me to the String Programming Guide, and so on.
02:04You want to get comfortable with looking up Class References.
02:07So I am going to click that.
02:09It's going to open up the other window of Xcode, the Organizer window.
02:13It's taking me right now to the NSString Class Reference.
02:16There is a lot of information when you look in the Reference Library.
02:20There is a lot of information about strings.
02:22But as we come down, we'll see all the tasks we can perform, and these are
02:26basically telling us all the methods that exist.
02:29So for Creating and Initializing Strings we have a bunch of options.
02:32Creating and Initializing a String from a File, or URL, Getting Characters, and
02:37Bytes, Combining Strings, Dividing Strings, Finding Strings.
02:40There is a whole bunch of stuff going on here.
02:43In any of them I can take a look, say the Changing Case section, find one like
02:47uppercaseString, and click that to tell me a little bit more about this method.
02:52Now, what this one is telling me is that it's a method called uppercaseString
02:56and it's going to return a pointer to an NSString object, and the dash at the
03:00start of it shows me that it is an instance method.
03:04So it needs an instance of the NSString object to work on.
03:07Okay, so how might we use it?
03:09Well, I jump back into this code here, and I do have an instance to work on.
03:13I've got an instance called message.
03:15So while I could actually just use my Square Brackets and say
03:19message uppercaseString.
03:21Well, it's going to return a new NSString pointer.
03:26I need somewhere to put it.
03:27So I better create a new one.
03:31I'll call it message2.
03:33Sure, we're working with basic, basic stuff here, but just to prove that this
03:37works, let's put down NSLog, The result is, and the placeholder that I need to
03:43use for a string is not percent sign i, or percent sign c, or percent sign f,
03:47but percent sign, @ sign.
03:49Actually that isn't specifically for a string.
03:52That's a placeholder for an object.
03:55So we're creating a simple NSString object or message on Line 9.
03:59We're then calling its uppercaseString method to return an uppercase version of
04:04it and store that in message2, and then we're outputting message2.
04:08Again, nothing particularly exciting, just talking about the kind of rationale
04:13for how we find what we're looking for, and of course spitting out the results.
04:17The result is HELLO in all uppercase. Fine.
04:20So what else can we do?
04:21Well, let's create a different kind of object.
04:23What I am going to do here is type NS and put in NSDate.
04:26Now, you'll notice as I start to type, we do have a bunch of different options here.
04:32If you look at the start of them, you'll see that there are different icons.
04:35Ks and Ts and Cs, and you'll see hash marks, all that kind of stuff.
04:40The C is representing a Class. So NSDate is fine.
04:44NSDate, it's a class, we're creating an object, so we need a pointer.
04:47I'll call it myDate.
04:48And now I am thinking, well, now what do I do, because I can't just create a
04:52date with say NSString object.
04:54So how do I create a date?
04:56Well, maybe I don't know.
04:57So the easy way to do this is I want to jump to the Date Class Reference.
05:01Well, I'd close down my Quick Help, so I could bring it back open again.
05:05But a quicker way and one that I use all the time and you probably will too
05:09is you hold down the Option key, and what will happen is your cursor changes
05:14into this little crosshair, and you mouse over the class that you're
05:17interested in, and click.
05:19What that does is pop-up a little window here telling you about the class,
05:24little bit of an introduction, and then telling you where it's Declared, and
05:27where the Reference is, even pointing me to the Date and Time Programming Guide.
05:30That looks pretty interesting, but really all I need is the Class
05:33Reference right now.
05:35If I start looking through that, the best place to jump to is Tasks.
05:39What are the core tasks I want to do?
05:41Well, I want to Create and Initialize Date Object.
05:44I have a whole bunch of options here, but the first one is date.
05:47Let's take a look at that. Jump in there.
05:50It says that this will create and return a new date set to the current date and time.
05:54Yeah, it looks exactly what I'm looking for.
05:56In fact, it says the following code sample here that actually says how to get
06:00the current date, even storing it in a pointer object.
06:03So I'm going to just Copy that code and put that in here.
06:08So I'll write in NSDate date, and then I better prove that this one works.
06:13So we'll write out an NSLog message, The date is, and I need to put my
06:18placeholder, which will be percent sign, @ sign.
06:22Again, percent sign, @ sign is what we'll use for an NSString.
06:25It's what we'll use for an NSDate, because it's the generic placeholder for an
06:29object, and the name of my object was myDate.
06:33Save that, Run it, and we're getting both our messages out.
06:36the uppercase HELLO, and then just the output of the date and time.
06:41Again, not tremendously exciting stuff, but it does expose a couple of questions here.
06:45So I've written two lines that call methods.
06:50Line 10 calls the uppercaseString method of the message object and Line 14 calls
06:56the date method of the NSDate.
06:59Now, there is a big difference here, because on Line 10 I use the name of
07:04the object, the name of the instance, whereas on Line 14 I use the name of the class.
07:09So what's happening here?
07:10Well, if you are already familiar with object orientation, you'll know that
07:14there can be class methods and instance methods.
07:17That means when the classes are defined, some of the methods are designed only
07:22to work on an instance, whereas other methods are defined to work on the
07:26entire class itself.
07:28Now, the question is, well, how do you know?
07:29Well, it will tell you.
07:31If I go back into my NSDate Class Reference, again, I'll hit the Option key, and
07:36click over NSDate, jump into Class Reference.
07:39When I come down to see the different things I can do, notice that my Tasks here
07:44all begin with either a plus or a minus sign.
07:48Now, if you're coming from something like C# or Java, you'll be forgiven for
07:51thinking this might mean public or private. It doesn't.
07:54The plus sign means these are class methods and the minus sign means these
07:59are instance methods.
08:01The immediate impact of that means that when I am using the square brackets to
08:05call them, Objective-C will make sure I'm doing the right thing.
08:09If I'm calling the uppercaseString method, Objective-C will make sure that I'm
08:13calling it on an instance on NSString.
08:16If however I'm calling the date method, Objective-C will make sure that I'm
08:20using the name of the class, which is NSDate.
08:24Now, we'll get a little more into class versus instance methods when we start to
08:28design our own, but that's that plus sign and minus sign, and you'll run into
08:32that as you start to look through the Class Reference documentation for your
08:37different available classes.
Collapse this transcript
6. Memory Management
What's new with memory management?
00:00When we make a new project in Xcode. whether that's a Command-line tool,
00:04or an iOS application, or a Mac desktop, or laptop application. We now have the option
00:09to turn on something called Automatic Reference Counting.
00:12This was made available with Xcode 4.2 in late 2011, so it was not an option when I
00:18first recorded this course and obviously for many years before that, and this rather innocent
00:22looking check box represents the biggest change to learning Objective-C, and it's a welcome change.
00:28Focus here on the word Automatic. What it means is by checking this something can now
00:33be done automatically that used to be done manually. Meaning we used to have to write
00:37code and with this checked we don't have to write that code anymore, and that code is
00:41all about memory management, but I can't explain what this is doing automatically until we
00:47see what it would do manually. So here's how we're going to do this.
00:51The next four movies cover conventional manual memory management in Objective-C. Memory Management
00:59as you had to do it prior to late 2011, so any Objective-C project you'd run into that
01:04was created before that, which also means a lot of what you'll see for sample code out
01:09there on the web, and how it is even right now if you have that check box unchecked.
01:14If you're going to be doing Objective-C, you need to understand manual memory management.
01:20Even if you don't have to actually do it anymore, and it's only from watching the next four
01:24movies that I can then talk about the Automatic Reference Counting feature, and you'll understand
01:29why it's important, how it works, and why you'll really enjoy having it. And towards the end
01:35of this course I'll also talk about upgrading older projects, projects created before late
01:402011, so they can use the new Automatic Reference Counting feature.
01:45
Collapse this transcript
Memory management in Objective-C
00:00All right, next up, Memory Management, a term that strikes fear into the hearts
00:04of programmers everywhere, and it really shouldn't.
00:07See Objective-C wants you to manage memory for every object you create, not
00:13Ints, Floats, Chars, Bools but objects whether those objects are coming from
00:18your own classes or from classes in any of the other frameworks.
00:22Now the concept here isn't hard to understand.
00:25You write code to say when those objects are created, so you should write code
00:29to say when you're done with them.
00:32True in my languages things like Java, C#, Ruby, Python all the scripting
00:37languages, you don't really have to think about this.
00:40You just make the variables that you need and the language takes care of
00:44cleaning up your mess.
00:46This is usually done by part of the language called a Garbage Collector.
00:50Now, Objective-C actually has a Garbage Collector kind of, see it wasn't
00:55originally part of the language, they added it a couple of years ago and we are
01:00not going to use it in this course.
01:01and there are four main reasons why not.
01:04One, the main one, Memory Management is a baseline core skill for any
01:12Objective-C developer, end of story.
01:14Two, garbage collection can't be used on the iPhone, it can't be used on the
01:18iPad, and it can't be used on Mac OS X versions prior to Leopard.
01:23So if you are going to write apps for any of those platforms you have to do
01:26manual memory management.
01:28Number three, unlike all the other garbage collection languages that I
01:32mentioned, garbage collection is never the default in Objective-C.
01:37You have to choose and change settings in your own project and often write code
01:42just to opt into garbage collection.
01:45and four, to even use garbage collection you have to understand the normal
01:50way of doing things.
01:51So even if your aim is to use it, step number one is understand manual memory management.
01:57And here's the secret.
01:58It's really not that bad.
02:00It may not be as easy as a scripting language but memory management in
02:04Objective-C is not that hard.
02:06It's not as bad as memory management in C and certainly not as bad as
02:11assembler, because we don't have to worry about manually taking care of memory
02:15addresses and that kind of thing in Objective-C, we use something called
02:19Reference Counting.
02:20So let's see how we get into that.
02:23Here's the way Reference Counting works.
02:25Your app start, so command line app, a desktop app, iPhone doesn't matter which,
02:30and an area of memory is available for your objects to use.
02:34You write code to create an object.
02:37Now, right now let's not worry too much about the code being used here.
02:40Whatever it is, an object is created and an area of memory is cleaned for that object.
02:46What you have is a pointer to an area of memory.
02:49What happens is that object gets what's called a retainCount. It's a number.
02:54It's a number saying who cares about this object?
02:57And when the object is created, the retainCount is 1.
03:01You then work with the object.
03:03Use the square brackets to call methods using the pointer and when you are done,
03:08you issue a call to release the object and the retainCount goes to 0.
03:15Objective-C then says hey!
03:17It's an object that nobody cares about and it blows away that area of memory and
03:21makes it available for another object to use.
03:24You never explicitly tell Objective-C to destroy the object, you simply release it.
03:29So that doesn't seem so hard and it isn't if your application is as simple as this.
03:35The issue is what happens when you start creating objects and passing them around?
03:39So let's kind of recap this idea.
03:42We issue a line of code to create the object.
03:44It's created with the retainCount of 1.
03:46Well instead of then just using that pointer what happens if I call some other
03:52method of some other object and I pass this one in.
03:55Can I then immediately release it? Well possibly.
03:58So what should happen is that in the method that I am passing it to, they issue
04:04what's called a Retain Message and that would up the retainCount to 2.
04:10They get rid of it, they issue their own release.
04:13It takes the retainCount down to 1, I issue a release it takes retain to 0 and
04:18then it blows it away.
04:20But that's making the assumption that the method I am calling properly issued a retainCount.
04:25Here are the real two dangers when you're working with manual memory management.
04:29We create a class, we use that class, we release it.
04:36The memory goes away.
04:37What we still officially have is a variable called myObj in this case.
04:43This is what's referred to as a dangling pointer, and what that means is if
04:48after I release it, sometimes later I then try and use it, we have a problem on our hands.
04:55We're using the pointer to access an object that doesn't exist anymore.
05:00Now, the flip side of this is we might make another new object, we start to call
05:05the methods of it and then we don't release it.
05:07What we have here is a memory leak.
05:12Sure, no one is going to notice a small string or two but when you're working
05:15with audio, video, hundreds or thousands of complex objects, it adds up, and
05:20on the iPhone and iPad, this will often cause your app to be killed by the operating system.
05:25If you've ever been using an app on the iPhone and it suddenly just goes away
05:29and takes you back to the Home screen, that's usually why, and these two
05:33issues happen when people lose track of whether they should retain or they
05:37should release an object.
05:39And basically the way to be disciplined about this is to realize there really is
05:43one rule of memory management.
05:46If you own an object, it is your responsibility to release it.
05:51That kind of begs the question, what does that mean to own an object?
05:55Well, you own an object, if you created it or if you copied it or you retained it.
06:01Now it doesn't happen accidentally, there are specific words we will use in
06:05Objective-C to create, or copy, or retain an object and we haven't really
06:10used these words yet.
06:11But if these magic words are in your code they should be matched up with a
06:15release method call.
06:17Now, the flip side of this one rule just phrased a different way is if you don't
06:23own the object, you must not release it.
06:25So if you're not using these magical words to create, copy or retain it, you
06:30must not pair it with the release, because what's quite common particularly for
06:35beginning developers is they're not sure if they're supposed to release
06:38something, so they just release it just in case.
06:40Well, no, if you don't own the object, you must not release it.
06:45But really to get more into this we need to be specific about those words, what
06:50are those words that we use to manually take charge of creating objects?
06:55So we're going to get into that next.
Collapse this transcript
Object creation
00:00So we've created a few objects along the way.
00:02We've create some NSStrings, we have created some NSDates, but we haven't really
00:07been doing it the right way and here is the right way.
00:12Let's say our program begins and we've got some memory that we want to play with.
00:16I am going to write a line of a code to create an object correctly.
00:19I am using the NSDate class though I could use any class here, so I use the
00:25name of the class NSDate and then the asterisk meaning pointer.
00:29Then I am going to name my variable, I'll call it myDate and set it equal
00:33to [NSDate new], I am calling the new method of the NSDate class and I am calling
00:42this as a class method, I don't have an instance of this yet, I can't call
00:46an instance method.
00:48What this is going to do is actually create an instance, create an object for
00:53me and it does this in two stages, there are two very separate parts when I use new.
00:58The first stage is allocation.
01:00What that means is object C is going to out to that area of memory and carve out
01:05a space big enough to hold this object.
01:08The second stage is initialization.
01:11It's going to go through the object, figure out what it's made off and
01:14initialize variables internally that could be very simple.
01:18That could be very complex.
01:20It depends on the class definition and the final stage here is it's going to
01:24return the address in memory of that object that is what the pointer variable
01:29myDate will hold is the address of this object.
01:33All classes in Objective-C have a new method that will do both the allocation
01:39and initialization stages and I like to show this one because new is a very
01:44common keyword for object oriented languages for creating an object.
01:49However, even though you can use it in Objective-C, it's not that common.
01:53Because there are two stages allocation and initialization what you'll commonly
01:58see instead is those written explicitly, one part that just does the allocation.
02:04So in this case I am saying NSDate *myDate = NSDate alloc.
02:09alloc instead of new.
02:11That will go out to that area of memory, carve out the space and return the
02:16address in memory, I now have a pointer pointing to the area of memory.
02:20I have an instance of NSDate.
02:23What I'm then going to do is call the init method and it's an instance method
02:28here so I'll call it on myDate not on NSDate and that will go through and
02:33initialize this object and set the variables and do whatever the initialization
02:38needs to do there and this is the most common way that you'll see it in
02:41Objective-C is the explicit allocation and initialization done separately.
02:47Although because this is the most common way, you don't typically spread it
02:51across two lines you don't have to.
02:53You can nest one inside the other.
02:56So instead of it being written on two lines, you'll typically see it like
02:59this, a nested call first to alloc which returns the instance and then to init on the instance.
03:08This is the most common way that you will see object instantiation in Objective-C.
03:14You will see it all over the place.
03:16It will just follow this general pattern, class name, class alloc, init, Person
03:20alloc, init, Dog alloc, init, customer alloc, init, or even NSAutoReleasePool =
03:27NSAutoreleasePool alloc init, if this looks vaguely familiar that's because this
03:32last line here is the first line you're going to see on pretty much any project
03:36that you make an in X code.
03:38It's setting up the AutoReleasePool, with the explicit allocation and
03:43initialization stages.
03:44Now what's quite common depending on what language you come from is you might
03:47look at this and think well, why on earth would I want to do the nested call
03:52and the alloc init when I could just say new and new would do exactly the same thing?
03:56Well, there is a great reason.
03:59You see you'd often don't just have an init method, you often have several init methods.
04:05So we might do an allocation and then we have a slightly different
04:09initializer method.
04:11You might have init with name when you're creating a person object and it allows
04:15you to pass some information into that, initializer that when you're working
04:20with an NSString, there is actually an init method called init with contents of
04:24files, there is init with contents of URL, there is init with CString.
04:28There's a whole bunch of different ways to initialize that object.
04:33With the NSDate there is an init with time interval since 1970 that just expects
04:39some seconds to be passed in.
04:41These are all multiple ways to control the instantiation and the initialization
04:46of an object and you wouldn't help them if you just used new.
04:51So that's the big reason for it.
04:53But here's the thing.
04:55alloc is one of those magic words.
04:57If you have written some code for any class that says alloc and init, any of the
05:02inits, or you've written new, then congratulations!
05:06You, I know the proud owner of an object and it is your responsibility to release that.
05:13An object is not just for Christmas.
05:14It's for life or at least the lifetime of your program if you're not careful and
05:19if you don't control the lifetime.
05:21So let's revisit this and see what would actually do here, back to our
05:25little memory space.
05:27We run the line of code that creates the object with an alloc and init.
05:31It grabs the space. It initializes it.
05:34It returns the address and puts it in our pointer.
05:37We then use that pointer to access the methods of that object and play around
05:42with and do whatever we want with it.
05:43When we're done, we use the pointer and we call release on that object.
05:50That will take our retain count down to zero and although you can control
05:55exactly when at some point the Objective-C runtime will say okay, nobody's using
05:59that object anymore, I can reclaim that space, I can use it for something else.
06:03Now something to be aware of:
06:06technically at this point you still have the pointer variable myDate which still
06:13contains an address in memory.
06:16Well, you had to have up to this point because you just called release on that
06:20pointer and you had to have the pointer around and that's not a terrible problem
06:25although this technically is a dangling pointer.
06:27You don't want to use the pointer myDate anymore.
06:30You don't want to accidentally try and send a message to that object that no longer exists.
06:36What you can do it's optional, you don't have to, is you can set myDate = nil.
06:42not null, but nil, N-I-L is the word that we use here.
06:46What that will do is clear out that address in that pointer variable.
06:52Now an interesting point for those of you from other object-oriented languages
06:56technically at this point, I actually could try and call a method on myDate.
07:02If you try and send a message to a nil object, it will just be ignored at one
07:05crash your program the way some languages would.
07:08It's not really a big deal because after all there is no point whatsoever
07:12in trying to do there.
07:13So hopefully it won't happen anyway, but technically you could do it.
07:17Although this code is very simple, the alloc, init is the classic way to
07:22instantiate or create a new object and if you're going to have that, you need to
07:27release the object as well.
07:29It's your responsibility.
Collapse this transcript
Using autorelease pools
00:00If you use any of the magic words in working with your objects, you use Alloc,
00:05you use New, or you use Retain, or you use Copy.
00:10Those are those indicators that tell you it's your responsibility to match one
00:14of those with a release.
00:16Let's say we start off with something simple, we just do a basic Alloc in init
00:20to create that object.
00:21The object is created with a retain kind of 1.
00:24You then use that pointer to access the methods of that object, but at some
00:28point it's your responsibility to create a release, because you used the word Alloc.
00:32You then call release, the retainCount goes to zero and it gets taken care of,
00:36you've done your duty.
00:38If you do a little more, you create the object with Alloc in it and then you say
00:43call retain on the object, the retain goes up to two, you'll call it again, the
00:47retain goes up to three, you call it again, the retain kind of keeps going up.
00:52You need to match each of those calls to retain with a release.
00:56it's always your responsibility to take it back down to zero.
01:00But you have one more option.
01:04anytime you call release on an object, you could substitute that with the word
01:09auto-release instead.
01:11Now this has nothing to do with garbage collection, don't be misled by this word
01:15auto, you're still very involved here in memory management.
01:19Release means release it now, reduce the retainCount now.
01:23auto-release means release it later.
01:25Well, there is a vague term if ever there was one, what does it mean later?
01:30Well you see, when you call auto-release.
01:33instead of immediately reducing the retainCount, what it does is it adds an
01:37entry to something called the Auto-release pool.
01:40An Auto-release pool sounds complex. It isn't.
01:43It's just a list of objects that need to have release called on them at
01:48some point later on.
01:49And when you call auto-release on your object, it adds it to that list.
01:54Let's say along with a bunch of other objects that might be added by
01:57different parts of your code.
01:58Your code continues on, and at sometime in the future there is a call to drain
02:03the pool, this sounds complex too, isn't it?
02:07It just means go through the list and call release on every single object in the list.
02:14So when is the pool drain?
02:15Well, in a typical command-line tool that we've been working with, on line 19
02:20here, the pool is drained.
02:21it basically means all your auto- release objects will be released right at the
02:25end of the main function.
02:26That's pretty simple.
02:27That's for the command-line tool that's designed just to blast through and
02:30finish as quickly as possible.
02:32And in iPhone or a Desktop app, which could be running for a lot longer, the
02:36default behavior is that the auto- release pool is drained repeatedly at the end
02:41of every event loop.
02:42Well, what's an event loop?
02:43Something like touching a button in the application, the button goes and does
02:48what it needs to do and comes back to the normal state of the app.
02:51That would be an event loop.
02:52So the pool might only last for milliseconds before it is drained.
02:56The objects don't just hang around for some random time.
03:00Now my suggestion is that early on in your Objective-C career you avoid writing
03:05the word auto-release as much as possible.
03:07And it's not because of performance or memory implications.
03:11Sure, if you're using auto-release your objects are lasting longer than they
03:15need to, but that's not the main issue.
03:17What happens is that I've seen many beginners that tend to use auto-release all
03:21the time, because they're not quite sure if they can call release properly.
03:25And if that's the reason you need to become sure and figure out how to really
03:30release an object, they should never be a coin toss, maybe I'll use
03:35auto-release, maybe I'll use release, there are very specific times that you
03:39should use auto-release, let me show you one.
03:42The deal is you write a method that needs to create and return an object.
03:47this is often referred to as a Factory Method.
03:49You don't know who's going to call this method. It doesn't matter.
03:52You're creating an object, you're going to return it, but hang on, you've used
03:57the magic word Alloc, and you haven't paired it with the release, but it's your
04:01responsibility to do that.
04:02Where you'd write the code that says release.
04:03You can do it after the return.
04:07you'll never hit this line.
04:08Soon as you'd hit Return, you'll jump out of the method.
04:11We can't put it before the return, because at this point where the retainCount
04:15would drop to zero and the object could be reclaimed, so instead what you do is
04:20replace the call to release with a call to auto-release.
04:24You now know that release will be called on this object at some point in the future.
04:30You've done your duty.
04:31you've taken care of your responsibilities.
04:33The object will last long enough to pass back to have a call this method.
04:38Now whoever called this method should hopefully be calling retain on the object,
04:42if they want to keep it around, but that's their problem and it's their
04:45responsibility to release it later.
04:47You've taken care of your part of the problem here.
04:51So that's how to manually auto-release objects and work with auto-release pools.
04:56Throughout those lines that we've seen in our projects all along are all about
04:59is auto-release pools.
05:01However, even if you never write the word auto-release, you may still end up
05:07with a lot of auto-released objects, and next up I'll show you why?
Collapse this transcript
Apple autoreleased objects
00:01So we spent a lot of time focusing on those words new, alloc, retain, and copy.
00:06But as you've probably detected and seen in some of the code we have written so
00:09far, we can still end up with objects without having used those words.
00:14So what's the deal?
00:15I am looking at a bit of simple code here.
00:17I've written some code that creates six objects, three NSStrings, and three NSDates.
00:22And we've seen most of these, but a couple of them are new, so I'll go
00:25through them line by line.
00:26Line 8 creates an NSString object, just centered to do the word Hello.
00:30We've seen that one before.
00:32Line 9 and 10 is creating another NSString using something called the
00:36stringWithFormat method of the NSString class.
00:39And this is a simple way of creating a string using the same kind of format
00:45specifiers that we've been using in our NSLog messages where we can put
00:49placeholders in the string and fill the values out when the program runs.
00:54And very similar to that, below on line 11 and 12 I am using something
00:57called initWithFormat.
00:59Looks very similar but I can see that I also have to do an NSString alloc and I
01:04am doing that manually on line 12.
01:06Coming down the line 14, this is the way that we can create an NSDate object and
01:11just set it to the date and time right now.
01:14On line 15 we're creating another NSDate with the dateWithTimeIntervalSince1970
01:20passing in a certain amount of seconds.
01:22And then on line 16 we're creating a third NSDate object by copying the first one.
01:26On line 18 I'll spit them out in an NSLog message but I am trying to be a
01:31good Objective-C coder.
01:33So the question is, which ones do I now need to release?
01:38And for that it always goes back to new, alloc, retain, and copy.
01:43Or if you prefer we could use just the word 'narc' to remember that.
01:47So if I just quickly scan that code, I don't even need to really know what those
01:53methods do and what they are.
01:55I am just scanning for those words and I see them in precisely two places.
01:59I see the word alloc on line 12 and I see the word copy on line 16.
02:04And what that immediately tells me is I need two release calls.
02:08one for anotherMessage, and one for anotherDate.
02:14The other four objects, I don't need to call release.
02:17So what's going on here?
02:19May are they some kind of special with pseudo-object.
02:21no, they're all real objects.
02:24They're regular objects.
02:25But when you get hold of an object by using say the stringWithFormat method on
02:31line 10, you can make the assumption that these are autoreleased objects.
02:36What's happening is that there are a lot of shortcut helper methods like
02:40stringWithFormat and dateWithTimeInterval and just the NSDate date method that
02:45are creating and returning objects.
02:47And you can make the assumption that whatever is going on inside the NSString
02:51stringWithFormat method, first allocs and inits a string object and then calls
02:57autorelease on it before it returns it to you.
03:00And that means you don't call release or autorelease on these objects, because
03:05it's already been done.
03:06Now I am occasionally asked, well, should I call release or autorelease just in
03:10case just to make sure?
03:12And the answer is, No, absolutely not.
03:14Because those objects have already been added to the autorelease pool and you
03:18can mess things up if you called either release or autorelease on them.
03:22It always goes back to that narc word.
03:24If you didn't use new, alloc, retain, or copy, you don't own that object.
03:31And if you don't own it, not only don't you have to call release on it, you must
03:36not call release on it.
Collapse this transcript
Introduction to Automatic Reference Counting (ARC)
00:00So that was Manual Reference Counting, conventional memory management in
00:05Objective-C, and still a very valuable thing to know about. But let's talk about ARC, or
00:09Automatic Reference Counting. Made available at the end of 2011, and here's the great thing about it.
00:14ARC is not something you have to be an expert on, it's something the compiler does, although
00:19you need to understand what it's doing, so you can let it make your life easier.
00:24ARC is all about simplifying that Memory Management Code that most difficult, most tedious, the
00:29largest cause of bugs in any Objective-C program.
00:32As we have seen, we use reference counting in Objective-C. We create objects using alloc
00:37and init, or other variance of that. We use the object, but then we better take care of
00:42releasing that object once we're done, so that, that memory can be reclaimed.
00:47Now, with one object and three lines of code, this is not a huge problem. But when you have dozens
00:51or hundreds or thousands of objects being created, manipulated, passed around from method
00:56to method or object to object, and you have to keep track of them all, calling retain
01:01on objects when you pass them around, so they don't get released too soon, and then matching
01:05that up with the release call as soon as possible. You really have to envision every possible
01:10path through the logic of your application, and this can be painstaking work.
01:15If you create an object, and then release it too soon, you can have dangling pointers,
01:21and dangling pointers can crash your program if you then try and use them.
01:26On the other hand, if you create objects and release them too late, or don't release them
01:31at all, and then you have memory leaks, and the bigger your applications get, the harder
01:36this gets to create successfully.
01:39So Memory Management Code is the main reason why a lot of people give up learning Objective-C,
01:44it's the main reason that applications take longer to develop or don't get finished at
01:47all, and it's the main reason that finished applications crash, which itself is the biggest
01:53reason why certain apps are rejected from the iOS or Mac App Store.
01:58But with ARC, the question of when to retain and when to release pretty much goes away.
02:04You don't write release calls anymore, you don't write retain calls anymore, you don't
02:09think about that. You create your objects the usual way, and then you just use them.
02:15That's it! ARC, Automatic Reference Counting takes care of cleaning things up.
02:20Now, here's the really important thing to understand. The idea of retain and release
02:25calls has not disappeared, Objective-C still uses reference counting. The language has not changed.
02:31The only difference is you don't write the retain and release calls anymore, the compiler does.
02:39ARC is taking the fact that compilers have gotten so good that anytime you build your
02:44project, the compiler--in this case the Compiler called LLVM, which is what Xcode uses behind
02:49the scenes--is able to scan through your code and determine all the possible paths through
02:54it, figure out where your objects are being used and where they are not, and synthesize
02:58the retain and release calls at the best point in your program.
03:02The compiler is effectively generating the same code that you would write yourself if
03:07you were really, really good at writing memory management code. Okay, you won't actually
03:12see these lines being added to your code, it doesn't physically change your source code
03:16files, but this is effectively what it's doing when you compile or build your project.
03:22And with ARC turned on, and yes, you can turn it off, but it is on for a new project by
03:27default in Xcode, you will never have to write a release call again, never write a retain
03:32call again or an auto release call. And not only don't you not write this code, with ARC
03:38turned on, you can't write this code. If you try and write a simple release call, the compiler
03:45will complain, Xcode will reject it and make you take it out.
03:49So for the most part, learning ARC is simply learning what it is you don't do anymore.
03:53And in fact, you can take what I have told you in the past few minutes and just go ahead
03:57and make a new project and run with it. You're good to go. That's it! Well, okay, there are
04:02a few other pieces worth knowing. So I am going to talk about some extra things about
04:06ARC that might be useful to know and some gotchas to be aware of. But you now know the
04:11impact of day to day use of ARC, which is pretty much, don't worry about writing retain
04:16or release or auto release calls.
04:19Create your objects the usual way using alloc and init, use them, and you're done. And perhaps
04:25the best thing about ARC is it will let you concentrate your mental effort on your actual
04:30problem on the interesting stuff about the application you want to make, instead of the
04:35headaches of memory management.
04:36ARC is really, really good at this, and you should be using it in every new Objective-C
04:41project you create from now on.
04:51
Collapse this transcript
What ARC manages
00:00Automatic Reference Counting, ARC, deals with Objective-C objects.
00:04Nothing changes about how you use inits, or floats, or chars, just objects. And nothing changes
00:10about the way you create your objects. You don't make your objects in some special new
00:15way, you use alloc, init, or convenience methods, the same way that you always have, and we
00:20still use these pointers to our objects. And it's your pointer variables that are the most
00:25important piece of the ARC world.
00:27It's how ARC can detect this object is still relevant. As long as it can tell that there
00:32is a variable that's accessible, that's in scope, somewhere in your application, and it
00:37points to as a reference to an object, that object will continue to exist.
00:42So ARC considers these normal object variables, regular pointer like these, as being what are
00:48called strong references. It is possible to create what's called a weak reference, but
00:53that's a topic for another time, and it's a regular strong reference that keeps the
00:59object alive, and as it goes through your code, when ARC detects that there are no more
01:04strong references to an object, perhaps their variable pointing to it has gone out of scope,
01:09or it's been set to something else, or even been set to nil. ARC will generate the code
01:14to release the object and the memory will be reclaimed. That's important to understand
01:20that ARC is not garbage collection. If you have experience in a garbage collected language
01:25like C#, or Java, recognize that ARC is not the same thing at all because while it is
01:31automatic memory management, it's being done at compile-time, not at runtime.
01:37Garbage collected languages need a constantly running part of the runtime that monitors
01:41memory usage of an application, and then it jumps in to clean up when things get too big.
01:46This is what's often referred to with the wonderful term of non-deterministic finalization,
01:50meaning, you can't determine, you don't know exactly when it will happen, and that can lead
01:56to slow downs in garbage collected applications when memory is being reclaimed because it happens unpredictably.
02:02This wasn't acceptable to Apple and garbage collection as a technique for memory management
02:07was never implemented in iOS, although it did exist in Cocoa on the Mac Desktop.
02:14But another garbage collection as a technique in Apple development now pretty much goes
02:18away, forget about it, and we are not going to cover in this course. ARC is a much better
02:23way of doing it. We don't have some big memory management layer that's slowing our application
02:28down at runtime. It's exactly the same runtime model as before because it's the compiler
02:34that's already done the work of figuring out exactly where that memory management code
02:39should go before the application is ever run.
02:45
Collapse this transcript
The rules of ARC
00:00Apple has a handful of formal rules for using automatic reference counting,
00:05it's not really a chore to have to memorize these rules because if you break any of them
00:09you'll get an immediate error and your program won't even compile, it will be obvious.
00:14Now the rules are there simply so ARC can always figure out exactly what to do.
00:20Only two of these rules are significant for all developers. And you'll find a few of the others
00:24to be edge cases that you're much more unlikely to run into because they deal with legacy code.
00:30So I'm going to show you the most important rules here putting my two most important ones first.
00:36Number one, don't call memory management methods, you can't write retain or release or auto-release
00:42in your code. ARC is doing the reference counting, it's doing the retaining, it's doing the releasing
00:47and you aren't, so don't get in the way.
00:50A side effect of this is you can also no longer access the retain count property of any object
00:55that will be disallowed and there is no reason to look at it. Now there is a less common
01:00side effect of this, you can't explicitly call the method called dealloc.
01:05Now we haven't talked about dealloc yet, we will in the next chapter, but just think of
01:09it as the flip side of alloc. Every object is allocated as part of its creation and deallocated
01:16when it's destroyed, so all objects have alloc and dealloc methods.
01:21Interacting with dealloc was sometimes necessary with complex objects, using manual reference
01:27counting, but with ARC, you can't manually call this even if you wanted to. So here is
01:32a whole bunch of code you don't have to write anymore, and if you try to, Xcode will immediately
01:38complain and tell you that it's not allowed.
01:41So here is rule number two. You don't, and can't, use the NSAutoReleasePool object using
01:47automatic reference counting. Now the concept of an auto release poll that we talked about
01:51earlier, that still exists, it's exactly the same. But in the code, the old NSAutoReleasePool
01:58object is replaced by the @autoreleasepool keyword.
02:01Now I mentioned this earlier, that the old style code that was used for years, looked
02:06something like this. It generated the code using NSAutoReleasePool that was followed
02:11by a pool drain call. If you try to have this code in a project with ARC turned on you'll
02:18get an error message that this object is not allowed. And this is why instead of this style
02:24of code when you create a new project you'll see this style of code using the at @autoreleasepool block.
02:30And one of the great things is, as you'll see a little later, if you want to change a project
02:35from the older style to the newer style, so that you can turn on ARC, it will do this
02:39automatically for you. Now here's one more rule worth mentioning, no object references in C structs.
02:46Now I'm only going to mention this one in case you come from a plane C background and
02:51it's the second nature for you to make structs that you're manually managing using the malloc
02:56and free keywords. While you can still create structs, Objective-C after all is built on
03:01top of C, but you can't put object references inside of them because this is just too confusing
03:07for ARC to figure out.
03:09ARC wants to manage Objective-C objects, and it wants to manage all Objective-C objects.
03:13And it can deal with complex objects, multiple levels of objects inside other objects, just fine.
03:19But it can't deal with objects inside the old-school C structs that you're manually
03:24managing the memory of yourself. So you can't do it this way, and if you try you will get
03:29another error message.
03:31If you are a C programmer, you can still use structs, but if you want object references
03:36inside them, well, use objects as your data structures. Now if you don't come from a C
03:41background and you didn't even know you could write this code, well, you don't have to worry
03:45about this at all. Most Objective-C developers I work with don't manually create C structs
03:50or work with C-style memory allocation, so this is a non-issue for most people.
03:56There are a few other edge case rules, but they're mostly to deal with migrating older
03:59projects to ARC. And in the final chapter of this course I have added a movie on how to
04:04migrate non ARC projects to ARC. And I have put it towards the end of this course simply
04:09because I want to cover a few more ideas and concepts first before we see how to do it.
04:14But from this point on, if you're creating new project, you should always have ARC selected.
Collapse this transcript
7. Custom Classes
Creating your own classes
00:00Apple provides over a hundred classes in the Foundation framework, and there
00:04are hundreds, if not thousands more in the other available frameworks, but it won't be enough.
00:08You'll need to write your own classes and then create objects based on those classes.
00:14In Objective-C, classes are written in two very distinct sections, the interface and
00:19the implementation, usually done as two different files.
00:23The interface done in a .h file is the simplest part. This is the face that the class is presenting
00:29to the world. It announces what this class is promising to do, what methods it has, what
00:35properties are available. It doesn't say how any of it is done, it just says what's available.
00:41The second part, the implementation done in a .m file, well that's where the real work is done.
00:46The implementation must live up to the promises of the interface. It is the real
00:52code of the class, and here's how we do it.
00:54So I am jumping over to Xcode where I'm going to create a new Xcode project, this will be
00:59an OS X application. It is of course a Command-line tool. I am going to just call this CustomClass.
01:05Make sure that Automatic Reference Counting is turned on, and it's a Type of Foundation.
01:12I am just going to save it into my Documents folder, again it doesn't matter where this goes.
01:16I am using Xcode 4.3.3 here, as ever if you have a different version, you may see slightly
01:22different behavior. We have the standard main.m file, but what I am going to do is come up
01:27to my File menu in Xcode and add a new class to this project.
01:32If I come down to the New word, we have New File here. And when we are adding a new file,
01:38just like creating a new project we have a lot of different templates, a lot of different
01:41options we can select from. What I want to choose is under the Cocoa section under Mac
01:46OS X, and I want the first option here which is an Objective-C class, and I'll click Next.
01:52It's going to ask, what is this class called? Well, I'm going to create a class to hold
01:56some information about employees. Now class names should begin with an uppercase letter,
02:02it's one of the few things that we do in an uppercase letter with Objective-C, and it's
02:06not a technical requirement, it's just a style guideline. So I'll type the word Employee.
02:12Then Xcode is asking us, what is this new class a subclass of? We are in an object-oriented
02:17language, and yes we are always going to inherit from another class. Other languages might
02:22use the term child class, or derived class. We say we are a subclass of something.
02:27The default one that we are going to use, the superclass, is going to be NSObject.
02:33Every class you are ever going to work with in Objective-C ends up inheriting from NSObject. It is the
02:39base class, the parent, the superclass at the top of the tree, and it will work just
02:43fine for us here. We'll talk about what NSObject gives us a little more later on.
02:48So if I go ahead and click Next, it's asking do I want to add these to my custom class
02:54project. Yes, I do, so I'll click Create and what I can see is I have two files that have
02:58been added over here in my Project Navigator Employee.h and Employee.m.
03:04.h is our header file, it is our interface, and the .m file is our implementation.
03:13Technically, these don't actually have to be into separate files, you could put everything together in
03:17one file, but this is the way you'll almost always see it done. It's the most useful way,
03:22because your .h, your header file is that public face of the class, it's how you say
03:27what is it this class can do, and as you get more comfortable with Objective-C you'll find
03:31yourself just browsing and looking at other .h files that Apple have created to understand
03:36the capabilities of a particular class without having to look at the actual implementation of it.
03:42Now in many other object-oriented languages we create a new class by using the keyword, class.
03:45That's not what we do here. In Objective-C a class is made of these two parts using the
03:51keywords @interface, and the keywords @implementation, and as long as we have those two parts we have our class.
03:59So first, I'm going to go into the .h section, the interface for this class. This is where
04:03I describe the data and behavior that this class promises to provide, what properties
04:08and methods does it have. And I am going to start off with something fairly simple and straightforward.
04:13So inside the @interface, but before the @end, this is where we name our properties and methods.
04:20So I'm making an Employee class, and let's say I want this employee to have a name property
04:25and a birth date property and employee number property just those three pieces of data.
04:29Now there is a couple ways you can do this and I will talk more about this in a moment.
04:34We are going to start off with this Property NSString *name. The @property is an Objective-C
04:42keyword, then we have the type like creating a variable, it's type NSString, and because
04:47it's an object we need to have the pointer symbol. So this is the way we define it.
04:51I of course don't give it a value because all I am trying to say here is that every
04:55object created from this class will have its own NSString that can hold a name, and I'll
05:02add a couple more properties here, one will be of type NSDate we'll call it hireDate and
05:07another will be of type int, and we will call that one employeeNumber.
05:11So these are properties in Objective-C. Properties let us define the data each instance of our
05:16class should have, like variables they have a type and a name. Now if you have already done
05:20something with properties you might be thinking, well there is something missing, I usually
05:23see a bit more information with properties. And that is true, we are going to get to that
05:27in a second, I just want to show a very simple example right now.
05:31We're describing these properties in our interface, and we may need to do a little work in our
05:36implementation file to make sure that these properties will work correctly. There is a
05:40lot more to properties that's not visible just from these lines of code and later in
05:44this section we'll explore more about them. But before that I also need to describe what
05:49it is that every object of this class can do. So not just the data of this class, but
05:54its behavior as well. I need to describe the methods of this class.
05:59Defining methods is very similar to defining functions, and we can actually think of a method
06:03as a function that belongs to the class. It's the same idea, a named block of code that
06:08can take parameters and can return a value.
06:12Now because we don't want to get confused about whether something is a method or a C
06:16style function, here's the format for declaring a method in Objective-C, meaning we are just
06:21trying to say that this method exists, we are not yet saying what it does.
06:25So I want to create a generic method called someMethod here. Line 17 is how I might begin
06:32with something really simple. In the same way that when we work with functions, we are
06:36giving this method a name, someMethod. The word void is actually the return type of this
06:42method, meaning it doesn't return anything.
06:44Now when I am defining a method in the interface in Objective-C what I do is surround the return
06:49type with parentheses, and I do that at the start rather than at the end.
06:53Now if you remember when we looked some of the class reference libraries we would see
06:57a plus sign or a minus sign, and that's saying whether this method is for an individual
07:02instance of this class, or is it for the entire class. And that's what I'm doing here, I'm
07:07using the minus sign to say this method is an instance method, there will be a different
07:12copy of it for every instance of this class.
07:15The way I am defining this method here it doesn't take any parameters, which means I
07:20don't put anything after the method name, I just finish it with a semicolon.
07:24In the next movie I'll show you how you define other more complicated methods.
07:28Now you might be thinking, well, where is the opening and closing curly brace, where
07:32is all the functionality of this method? But again, we don't do any of that inside the
07:37interface file. All we are saying is that this method exists.
07:41So other code and other programmers could now look at this interface file and say, okay
07:46you have a method called someMethod, it doesn't take any parameters, and it returns void and
07:51it's for the instance. Okay I can use it, I can call it, I don't need to see anything else.
07:56But if we are making these promises, we now need to provide the implementation, the second
08:00part of the class, the actual code that provides the functionality that we are promising here.
08:05So I am going to jump into the Employee.m, our .m implementation file.
08:11And everything we do here will be inside the @implementation keyword, but before the @end. And I can already
08:18see that I have got this exclamation mark showing up here. If I click that, what it's going
08:23to tell me is there is a few problems, and in fact, there is seven problems right now.
08:27Because we're not providing the implementation of the promises that we made, so let's start doing that.
08:32I know that my interface has three properties that is three pieces of data and one method, one behavior.
08:38So let's first deal with the behavior. What I need to do is define the
08:43method, someMethod, exactly as it was defined in our header file. But provide the actual
08:49implementation for it.
08:50Now I can just copy and paste, or I can type this out in full here, and I can even see as
08:56I'm typing that it's helping me fill this out. But as opposed to just finishing it with
09:00a semicolon, in the implementation I need to do the opening and closing curly braces
09:05and actually have some kind of behavior here. And let's just put in a very simple NSLog message.
09:13I don't need a return statement here because this method returns void, meaning it doesn't
09:16return anything, but it's still complaining. And that's because in Xcode 4.3 and earlier,
09:23you need to match any property declaration in the header file with a corresponding synthesize
09:29statement in the implementation.
09:32That needs to be put inside the @implementation before the @end, so put it right after this.
09:38It is an @synthesize, and you notice as I'm typing this is popping up here.
09:43In Xcode 4.4 and above, this synthesize statement can happen automatically, otherwise we'd need
09:48to write it ourselves. What we're synthesizing are the properties we defined on the previous page.
09:53So we had the property called name. I could add another statement @synthesize for hireDate.
10:02I could add another synthesize statement for the employee number, or we could actually combine these.
10:08In fact, we can have one @synthesize line which is synthesize name, hireDate, and
10:16you see as I'm typing it's giving me the code sense employeeNumber. I finish that line with a semicolon.
10:23In short, what this synthesize statement is doing is to generate two methods for each property.
10:28One to set its value and one to retrieve or get its value, often referred
10:33to--not just in Objective-C, but in many other languages--as the property's getters and setter methods.
10:39Again, we'll talk more about that in just a moment.
10:42I could hit Command+B here to build this and we can see there are no issues.
10:46Build has succeeded, there is no warning signs up here, it looks good. Yes this is about as simple
10:52a class as you could possibly write, so let's prove that it works.
10:56I have my interface, I have my implementation, I'm going to jump across into a main.m where
11:01I am going to actually instantiate this class and use it. So I don't need the NSLog Hello
11:06World statement, but I do put my own code in the insert code here part inside the autoreleasepool block.
11:13I want to create a new instance of that employee class. Now if I start typing employee, it
11:18doesn't know what I am talking about. This file, this main.m, doesn't know about our Employee.h
11:25and Employee.m. The way that we tell it is we need a new import statement.
11:29The same way that right now on line 9 we are linking to the Foundation header file, I need
11:34to link to the employee header file. So I do that with another #import statement.
11:41When you're linking to Apple's header files, you typically use the less than and greater than signs.
11:45If you're linking to header files in your own project, you use the quotes.
11:50So inside the quotes here I am going to start typing Employee, and we can actually see that
11:54it's already bringing up the .h and .m. I need .h, so I'll hit the Return key to bring that in there.
12:01Now this main.m file knows about the Employee object, so I can actually create one.
12:07I'll create a new Employee, this is an object so it will be a pointer type. I'll call it fred
12:11and fred =, we'll do a standard object alloc and init creation.
12:18You might wonder, well where did alloc and init come from. Well, those methods are already
12:22defined as part of NSObject, and because we're inheriting from NSObject we will always have
12:28them, which is a good thing. We don't want to have to write our own code for every single
12:33object just to make sure that it can be instantiated.
12:36That line is giving us a warning, but this warning is actually just because we haven't
12:40used that variable. Well, that's okay, we are about to. I have got this pointer variable called
12:45fred, so that means in square brackets I can type the word fred, and then if I type
12:50S I am actually getting the pop up for someMethod, it recognizes that this object has this method inside it.
12:57If I save that and run it, what we should get is the actual popup and the little bit
13:03of text here that's saying we are in the method, which of course is the implementation that
13:07I provided in our implementation for that employee class. Very, very simple, but this
13:13is the way that we start to go about things.
13:15Now what we'll also find is that from the synthesize statement that we had in our implementation,
13:21that Objective-C and Xcode has actually generated two methods for each of these properties,
13:26one to set its value and one to get its value.
13:29Now what that means is I can actually then use this fred keyword, and I would find that
13:34if I typed the set word we'd actually have three methods here, setName, setHireDate,
13:39setEmployeeNumber as well as a whole bunch of other internally created methods.
13:45However, I'm going to avoid these right now. So obviously we are not doing much with this
13:49class, with this object, but this is the basic approach. But to get a better understanding
13:54and to start to use more pieces about it, we need to take a closer look at both methods and properties.
14:05
Collapse this transcript
Defining methods
00:00To declare a method in Objective-C, to add this in our interfacing--say that this
00:04method exists--you need atleast three pieces. The first thing is going to be the indicator
00:09that says is this a class or an instance method? If it's a class method, we'd use a
00:14Plus sign, and the method has to be called using the name of the class itself.
00:18But if it's an instance method, which is much more typical, we would use the Minus sign.
00:23Another method has to be called using a particular instance of that class. And the method needs
00:28a return type, and this is in parentheses. In this case, it's void, meaning where explicitly
00:33saying, this method doesn't return anything but it could return an int or float or bool
00:37or a pointer to an NSString object or anything else. And after that, not surprisingly, the name.
00:43What are we calling this method?
00:45And if the method doesn't take any parameters, you just then finish off with the semicolon,
00:50and we are now ready to go and duplicate this method signature in our implementation,
00:55where we'd actually provide the code to say what it does. But how about a few more examples?
01:00What if we wanted a method that accepted a parameter or even more than one?
01:04So I am going to start here with a method that's been defined without any parameters.
01:10And I'll show you how we change it. So we'll give ourselves a bit more room before the
01:13semicolon, and if you remember the one we call a method and pass in an argument,
01:19we use the colon to separate the name of the method from the argument, and that's what we do here.
01:24We add a colon, and then we add two pieces of information. First, what is the type of the parameter?
01:31And second, what do we want to call that? So in this case we are saying
01:36that the timesTen method takes one integer as a parameter called param, and it also returns an integer.
01:43Do bear in mind that if you are accepting or returning object types, then you will typically
01:48need the asterisk to say that these are pointers. In this case, I am defining a createMessage
01:53method that accepts a pointer to an NSString called input, and returns a pointer to an
02:00NSString, which is why we're using the asterisks in both places.
02:03Now, what if we want to accept multiple parameters? Well, if you remember, when we're talking about
02:09calling methods with multiple parameters, that the actual method name itself splits
02:14into different sections divided by colons, it's one of the big differences between Objective-C and other languages.
02:20And that means that if you're defining your own methods, you need to do the same thing.
02:24So let's begin with a simple method that takes no parameters called addNumber. This returns
02:30an integer, and I can see by the Minus sign it's an instance level method, so we'll give
02:35ourselves a bit more room here, and we'll first turn this into a method that takes one
02:39parameter, by adding the colon, then the parameter type, which is integer, and then the parameter name of a.
02:45So this would right now stand-alone as a defined method. It's got a method name,
02:50then the colon, then the parameter type, and the name.
02:54Now what we need to do is add the second section to this. We are going to duplicate this whole
02:58piece, the part with the method name, the parameter type, and name. So I add a second section here.
03:03Now there is nothing in between these two pieces of the method name just
03:06spaces, and it's insignificant white space. I am just trying to make this a bit more readable.
03:11So again, it's a second part of the method name, then the colon, and then the parameter
03:16type, and the parameter name, and this is how we define a method with multiple parameters.
03:21This method would be considered addNumber: toNumber.
03:25So let's see an example of this in Xcode. I am going to create a new Xcode project here in Xcode 4.3.
03:31It will, of course, be a Command Line tool. I'll call it MethodsDemo.
03:36It's of Type Foundation, and I'll say that we are using Automatic Reference Counting, and
03:41I'll just save that in my Documents folder. Before I do anything else, I am going to go
03:45and add a new class to this project. So coming up to the File menu, we will select to add a new file.
03:49This will be an Objective-C class from the Cocoa section, click Next.
03:55I just want something simple, so I will call it MyClass, and it will be a Subclass of NSObject.
04:00I will click Next and choose to add this to my project and click Create, and we get the MyClass.h and MyClass.m.
04:07As you might imagine, it's actually very common to need to flip between the .h and .m files,
04:13and in fact, in Xcode 4 there is a very nice little helper that you can do to help you do this.
04:17I am going to select the .h file, and because I don't have a lot of screen real
04:22estate, I am just going to close the right-hand section because we really don't need it here.
04:27Now in the Editor section on the Toolbar where the three buttons are, I am going to find
04:31the middle button that looks like someone wearing a bow-tie and a dinner jacket, this
04:34is called the Assistant Editor.
04:36If I click that, what we are going to do is switch into a dual-pained Editor section.
04:41And what it should try and do by default is figure out that if I'm looking at the .h file,
04:46and the second section is going to show me the counterpart to that, which will be the
04:49.m, the implementation file.
04:52You can change what it's showing in the second section by using the Jump bar up at the top
04:56here, but this looks fine for me. Now because I don't have a lot of screen real estate,
05:00I'm going to close the Navigator section, too, to make this a bit more obvious here.
05:05So, interface on the left-hand side, implementation on the right. So first, in my interface I am
05:10going to define a method that's about as simple as you can possibly get. I will call it performAction,
05:16it takes no parameters, and returns void. If I was going to change this to accept one parameter
05:22before the semicolon, I put a colon after the performAction name, and then the type of
05:27the parameter I wanted to expect, in this case an integer, and then give that parameter a name.
05:31I will call it param.
05:33Next, I'll add another method. In this one I'm going to say returns an integer.
05:37I am going to make it take two parameters called a and b. It will be an instance method so
05:42we use the Minus sign. I'll say it returns an integer. I don't care what that's called.
05:46We call it addNumber:, now we define the first parameter which I'll say is an integer, called a,
05:54then a space, and then we define the second part of the method name. I will call it toNumber.
06:01Again, we commonly used camel case for our method names.
06:05And this second part also takes a parameter, so I'll put the colon and the parameter type
06:10which will also be an integer and the parameter name that will be b, and then the semicolon.
06:15Yes, Objective-C's way of doing this, does look a little unusual depending on the language
06:20that you are coming from, but after creating a few of these you will find them quite straightforward.
06:24So if I look over here in my implementation, I already have the warning sign that says
06:29this is an Incomplete Implementation. Because this implementation about this .m file needs
06:35to support the promises that the header file has made. So inside the body of the implementation
06:40but before the @ sign end, I need to support those promises.
06:44Now I could copy and paste from the header file, but there is a couple of ways to make
06:47this little quicker. If I put in the leading dash, now I know that there is a method
06:50called performAction that I have declared in my header files, so I am just going to type in p.
06:54And what I will instantly see is it will pop up. I have nicely typed the word
06:58void here, that's okay. This is a shortcut to the method names. If I select the one I
07:03want--we're actually on the one that we want right now, but I could move up and down with the
07:07cursor keys, then I am just going to hit Return, and it copies across that whole signature
07:12that yes it's performAction, it returns void, and it takes one parameter of type integer called param.
07:19Now I do have to do my opening and closing curly braces. I really just need to have the
07:23opening brace and then hit Return. Xcode jumps us into the body of this method, and I'll
07:28just put something simple in here like an NSLog message, you passed in the value, we
07:37have a Placeholder, and then we'll spit out the words param. This returns void, so I don't
07:42need an actual return statement from it.
07:44But we are still showing up as incomplete because I don't have the other implementation
07:49of the other method. So again, type the Minus sign, and I will type the first letter of the
07:54method I know I need to support which is a, and I have got it popping up already, addNumber: toNumber.
07:59Hit Return, we get the signature of it. Do my opening curly brace and hit
08:04Return again, it jumps us into the body of this.
08:07Now this one does need to return at least an integer, which is why we are seeing the warning
08:12sign popping up already, and this one will actually be simple. I'll just say return a+b.
08:18The two parameters that were passing in, and that will do it. I may not actually be using
08:23these methods yet, but that doesn't matter. If I save this and then hit Command+B to build,
08:28we should get Build Succeeded, because I have completed the implementation of what I have
08:33promised this class would provide in my interface.
Collapse this transcript
Defining properties
00:00The heart of all classes are your properties and your methods, meaning
00:03your data and the behavior that acts on that data. We just saw methods. Let's talk a bit more about properties.
00:09Now, to do this, I need to do just a small amount of history because we didn't always
00:13have properties in Objective-C. For a long time, to define the data for your classes,
00:19you would define an instance variable inside your interface, your header file.
00:24Instance variables, often referred to as ivars, are just defined as regular variables.
00:28There is no particular special keyword. And you'd put these in your .h file and all your
00:33instance variables whether 1 or 100 would group together inside a set of curly braces.
00:39Now, you can still do this, and you will still see code like this from time to time. In Objective-C,
00:45other common thing is to name instance variables with a leading underscore.
00:49I haven't done that here. It makes no technical difference. it was just a common style habit to make it
00:54obvious when reading code.
00:55But here's the problem. In Objective-C, instance variables by default can't be accessed directly
01:01from outside the class they're defined in. What that means is that I can write code inside
01:05this class to manipulate, in this case this score variable, but it couldn't be directly
01:10accessed or changed from say a different class.
01:13Now, this is very common in object-oriented languages and not a bad thing. But if I wanted
01:18to allow another part of my program to get access to this variable, I had to create methods
01:24to allow it to be accessed, what are typically referred to as Accessor Methods.
01:29So it add two method definitions, one to get this value and one to set it. What I am defining
01:36here is what's often referred to as your getter and setter methods.
01:39Now, in other languages, it will be quite common to call these methods getScore and
01:43setScore, but in Objective-C, it's been the standard for many years to have the getter
01:48have the same name as the instance variable, although if the instance variable had a leading
01:53underscore, we would not include that.
01:55So, in this example, I declare a score method that would return an integer, and the other
02:01method would return void, and it would be called setScore, and it will take one parameter which
02:06is also an integer, and then what I'd have to do is in the implementation file, we'd
02:11actually have to provide the implementation for these methods.
02:15This is not too bad for one or two instance variables, but it makes for a lot of tedious
02:20code to continually have to write accessor methods. So, a few years ago, Objective-C
02:25added the idea of properties with a new keyword @property. A, @property is really a way of
02:31automatically generating or synthesizing these accessor methods.
02:36So back into the implementation example, instead of the two method declarations in the interface
02:42file, we add an @property keyword with a type and with a name. And over in the matching
02:47@implementation file, this is where we really save work. Instead of providing these accessor
02:53methods in full, we just add the @synthesize statement that matches the @property statement
03:00in the interface, and that will generate the getter and setter accessor methods.
03:04Now, after properties were introduced in Objective-C, it was very common for a long time to see
03:10this format. You would still have your instance variables defined inside the set of curly
03:14braces at the top of your interface, and you would have a matching property with the same
03:19name and the same type, and this property would automatically be wrapping this instance variable.
03:25But if you think about it, if we're defining the property and giving it a name and a type,
03:30we really don't need the instance variable anymore. And these days, that section has gone away.
03:34Apple's best practice as of mid-2012 is not to have any instance variables
03:40in your interface, so you don't need those curly braces, and you just create all your
03:45publicly accessible data purely with @property statements. And these are matched with the
03:50@synthesize statements in Xcode 4.3 and earlier.
03:54But here's the other thing. As these @synthesize statements really correspond directly to @property
04:00statements, we don't really need these either, and as I have mentioned in Xcode 4.4 and above,
04:04you don't even need the @synthesize statement anymore because it's something else the compiler
04:09can figure out from the fact that you wrote the property.
04:12It's another example that as time goes by, things get slowly simpler in Objective-C,
04:17but often these simple things hide quite a lot of behavior under the hood.
04:21Now, you might be thinking, well, if I don't have to do these instance variables anymore,
04:26why point it out? Well, as with ARC, I point it out because you will still see this format
04:31when reading sample code and reading books and presentations. It's still very common
04:35to see because it was around for many, many years of Objective-C.
04:39But now, while a simple property is just that keyword @property followed by the type and
04:45the name, like int and score, there is something else. Properties also have optional attributes
04:51which are written in parentheses after the @property keyword.
04:54Now, when your properties are primitive types like ints and floats, you don't need anything
04:59here, but with objects, you'll almost always need something. This is the most common one
05:05you will see with objects, the word strong, in parentheses before the type. Strong has to do with ARC.
05:12We're saying that this property should be considered a strong reference to this NSString
05:16object, meaning that we're saying we own it and as long as we keep our pointer to it,
05:21ARC will keep this object alive, and we don't have to worry about either retaining or releasing it.
05:27Now, you can also use the word weak here to define a property as a weak reference.
05:32And that means the object will only live while some other object holds a strong reference to it.
05:37A weak reference by itself would not be enough for ARC to keep this object in existence.
05:43But weak references are much less common than strong references, and they're not something
05:47we'll really need in this course.
05:49There are a few other words that can be put here, and some of these can be mixed and matched.
05:54If for example, you wanted to make a read-only property, you can add the keyword readonly
05:58in these parentheses, and that tells Objective-C to just synthesize a getter accessor method and not a setter.
06:06The default is read/write, so you don't need to write that. If you're developing iOS applications,
06:12you will also see words like nonatomic and atomic. But right now, we don't need those,
06:17we just need a basic awareness of properties.
06:20Now, one question you might have is what if we actually want an instance variable that's
06:25not a property, if it doesn't need to be accessed from outside the class, we just want it to
06:30find some variables to use inside the class?
06:33That's a very common name. The current best practice is that you can still use instance
06:38variables but don't define them in the interface, not in the .h file, but actually in the .m@implementation,
06:45because after all, the interface is the public face of the class.
06:49So instead, if we have instance variables, now the best practice is to put them in the
06:53implementation, or .m file. By convention, these go right at the top inside a pair of
06:59curly braces right after the @implementation line, and then it will be followed by your method implementation.
07:05So, while you will still see instance variables being put in the .h interface file, it will
07:11be much more common over coming years to see them only in the implementation and to see
07:16all of your data actually defined by properties in your interface.
Collapse this transcript
Defining initializers
00:00Every single class you will use an Objective-C has an instance method called init.
00:03We know this, we have used it already. Typically, we see init used alongside alloc,
00:10and init is there to initialize a new object. Make sure that it's created in a valid state,
00:16but if necessary, all its internal values are set to some meaningful amount.
00:21And all classes have this method because init is defined in NSObject, and because we were inheriting from that.
00:26Either directly or indirectly, we will have an init method.
00:31But it's our choice whether to write a custom version of init, specifically for our new
00:36custom class, so that we can say exactly how all our new objects or new instances are initialized
00:42as soon as they are created, and here's how.
00:46I'll create another Command Line tool application here. I'll call it InitializerDemo, Type of Foundation,
00:54and I'll check the box to say we want to Use Automatic Reference Counting,
01:00and I'll just save this to my Documents folder. You can put it wherever you like.
01:04Before I do anything else, I'm going to add a new class to this project. Up to the File
01:10menu, I'll select New > File. It will be a Cocoa Objective-C class, and I'm going to call it
01:17Player and make sure that we're inheriting from, we are a Subclass of NSObject. Click Next, and click Create.
01:27We have our Player.h and our Player.m files. Now I can write an init method in this class myself.
01:34I'll go into my Player.m file, and it would be in the body of the implementation,
01:39but there's an easier way than writing it. I'm going to make sure that my right-hand
01:43Utilities panel is turned on. If it's off, you can get it from the three buttons in the
01:48Toolbar, and what I'm interested in is the Code Snippet Library, which is the second
01:53button in the lower section, the one that looks like a pair of curly braces.
01:56There are a lot of different Code Snippets in here, the one that I'm interested in is
02:01the template for an init method. Now I can go down here, you'll find it under Objective-C
02:06Init method, although another quick way is you could filter using the textbox at the
02:11bottom and just type in init, and there we have Objective-C Init method. I'm going to
02:16click that and drag it directly into my implementation file, we are dragging it into Player.m, and let go.
02:24This is Apple's suggested code for a custom init method. It's the correct signature which
02:29is returning a type of ID. ID in Objective-C basically means any object, and that's the
02:35correct return type for any initializer method.
02:38So what else is happening here? Well, inside the body of init, we have a call to self = super init.
02:44Self is a keyword in Objective-C, which means the current object, here meaning, the
02:49object that has just been allocated and has caused this init method to be called. Other
02:54object-oriented languages might use the word this, or me, instead of self. It allows us
02:59to write code to refer to the current object without knowing the name of the variable that
03:04that object might have been called.
03:06Now super on the other hand is a keyword that refers to our super class, which in this case is NSObject.
03:10So here we're calling the init method that's already defined in NSObject,
03:16letting our super class do whatever it wants to do to hand back the current object.
03:21Now in the next line after this we ask if (self), we're just checking to see that this object exists.
03:26Now we would always expect this to work, but this is a best practice
03:30to detect some internal failure. Was there a problem calling the init method of the super class?
03:35But if we exist, then we're going to go ahead and run whatever initializations
03:40that we want to run.
03:42So here is where I'd write any code to do anything specific for my custom class.
03:46So let's make it do some initialization. I'm going to jump across to my header file because
03:50we don't have anything to initialize yet. I'm going to add a new property.
03:56The simple property of type init, and I'll call it score. Because I'm working with Xcode 4.3, I need
04:02to match that with a synthesize statement in the body of my implementation just to
04:07make sure that my access or method has generated.
04:09And then what I'm going to do is in this custom init method, I want to say that this score
04:15is going to be initialized as 5000. Now it's just an arbitrary value, but we need to initialize
04:20it to something, and that's how we guarantee that all objects instantiated from this class--
04:25whether that's 1 or 100 or 10,000--they will all be created with an initial score of 5000.
04:32So let's prove that. I'm going to jump across to main.m and instantiate an object of this class.
04:37So after the insert code comment, I'll create a new instance of Player.
04:42I'm going to find that it doesn't know what Player is right now because main.m doesn't have an
04:47import statement to our Player class. I'm going to add that after the import statement to Foundation.h.
04:52I'll add an import to Player.h.
04:56And again, if you're linking to header files in your own project, you'd use the double
05:00quotes as opposed to the angle brackets if you're linking to header files in Apple's APIs.
05:07Once we have linked to Player.h, I can now create a new instance of Player. It is, of course,
05:12an object, so it's a pointer type. I'll call it p, and we'll say that equal to the standard Player alloc init.
05:21We are allocating some memory and then we're going to call our custom
05:26initializer method to set up this object in the right way.
05:29Well, let's prove it. Right now it's given me a warning, because I'm not using that p reference yet.
05:34So I'll change the NSLog message to output an integer, and then we'll grab the
05:42contents of that by calling p score. I could use the square brackets here of p space score
05:49inside square brackets, or I could to use the dot syntax, which would be p.score, both would work. Save it. Run it.
05:57Build Succeeded, and down here when I run it, the score is 5000. So that object has
06:03been created in the initial state that we want it to be in.
06:08So this is a very easy way to do things. If you have some very straightforward and simple
06:13initialization tasks, just create your own init method and put in some simple initialization code.
06:18But what's more common is that you'll actually want a variety of initialization
06:23options, a variety of init methods. Well, what do I mean by that?
06:27Let's take a look at the Help file for some built-in classes that Objective-C gives us
06:31in the Foundation framework, such as say, NSDate. I actually have the NSDate Class Reference
06:37showing up here. If I hadn't got it, I could have searched from it over on the left-hand side.
06:41But if I look at this, I can actually see that NSDate gives me all these different
06:46tasks I can do. I can see that in the documentation I have an init method, but I also have initWithTimeIntervalSinceNow,
06:54initWithTimeInterval:sinceDate, initWithTimeIntervalSinceReferenceDate.
06:59There's a whole bunch of different methods that begin with the word init, and this is
07:04the convention in Objective-C, if what you want to do is have a variety of options for
07:10initialization, some that you don't need values or some that have values, a variety of custom
07:14ways to create an object.
07:17And again, as I like to make a lot of comparisons to other languages you might know, this is
07:21how we do the equivalent of the constructor idea in languages like Java or C#.
07:27In Objective-C we actually create totally different methods for the initialization process of our objects.
07:32We will always the alloc, and we'll have the regular init, but we might also have more custom init methods.
07:40So let's say that in my particular example here, the standard init method will always
07:45create this Player object with the score of 5000, but what if I want the option to create
07:49a Player object and maybe pass in 10,000 or 100 or -500 or 0? I want the choice when I
07:57make a new instance of Player.
07:59So I'll create another initializer method. So I'm just going to first start off by copying
08:05this first init and pasting it in, and I'll change one of them, and just change the name here.
08:11I'll change the first one, it doesn't matter which one I change, and I'll call this initWithInt.
08:16I know that there is nothing magical about the method name. Initializer methods are just
08:22regular methods. It's simply that by convention in Objective-C. If you want to write a custom
08:28initializer method, it should begin with the word init, and it's usually init with something,
08:33because you're describing what this expects. In my case initWithInt, it could be initWithString.
08:38I could have said initWithScore. But if I'm going to say this accepts a parameter, I'd
08:43better define that in the method. So we'll add the colon, and then say that the type
08:48I'm passing in will be an integer, and I'll call it s. Of course, I can call it whatever I want.
08:54So the idea is this method is called that passes in an int, and when I get that argument
08:59instead of setting it to 5000, I'll just say score = s, and that's my initialization code here.
09:05Now we have still got a bit of duplication going on between these two initializer methods,
09:09I'll tidy it up in a moment.
09:11The one extra thing before I start to use this, while we always have a plain init method
09:16because that's defined in NSObject, that's why we don't need to add an entry in the interface for init.
09:21But if I'm creating a more custom named init method that in this case takes
09:26an integer, well, I do have to declare that in my interface, in my header file.
09:31So I'm actually just going to copy the method signature of that custom initializer and jump into Player.h.
09:37I'm going to paste it in there and just end it with a semicolon because
09:43I need to do this to make sure that this initWithInt method is visible from outside this class.
09:50So now if I jump over to main.m and decide to create a new Player object, we alloc as
10:00usual, but as I start typing init, I can see we have got both the regular init method and
10:05we have initWithInt, that takes an integer. Well, let's try that one. I'll pass in 7500,
10:11that's just an integer, and just add a simple NSLog message. Save that. Run it.
10:19And what we can see here is that we are creating two different objects, the first one using
10:25the init method, which will write up its value as 5000, the second one using the custom initWithInt
10:31method, which will be created with 7500.
10:35So jumping back into the Implementation file, I have now got these two initializer methods,
10:41the typical init and the custom initWithInt, but we have a little bit of duplication still.
10:46Let's tidy that up. See, when you have multiple initializers in a class, you can usually contain
10:51the real behavior, the real work in just one of them and make the other initializer methods call int.
10:57Now typically the one that needs to do all the work is whatever one has the most parameters.
11:02In this case, it's initWithInt, because that has one parameter and the regular init has none.
11:08So in my regular init method, instead of having all these calls to super init and checking
11:14if self exists, what I'm just going to do instead is get rid of some of that code and
11:19say self =, and I'll call the other initWithInt method. In this case we wanted init to always
11:26start with 5000. So I'll pass that to that other method of this class.
11:31And again, we're using the word self here to refer to the current instance of this class.
11:37So now if from outside somebody calls the regular init, all we're going to do is call
11:42up to our new custom one passing in the value of 5000. In fact, I can shorten this even
11:47a little more and put that entire one on one line. Just a return statement and whatever
11:57comes back from calling initWithInt. Save that, run it again, and we get exactly the same value.
12:04I know that you don't always have to have a custom init method in your classes, but
12:09hopefully this makes it a bit more clear, not only how you do custom initialization
12:13when you need it, but also that when you have been creating things like NSStrings and NSDates
12:18and other objects. But when you type alloc and then type init, it's why you often get
12:23a whole bunch of different init options, because those are the custom initializers defined
12:28for those particular classes.
Collapse this transcript
Using dealloc
00:00As we have talked about the Initialization side of objects when they first
00:03get created, we should probably about the other, end too. What happens when an object is destroyed?
00:08Can we write code to interact with that part of the process? Well, of course,
00:13we can; however, it's often unnecessary, particularly with ARC.
00:17As we have seen, all classes inherit from NSObject, either directly or indirectly through another
00:24class, and that's why they all have an init method and an alloc method and more besides.
00:29But NSObject also defines a method called dealloc, which is automatically called at the
00:34end of an object's lifetime. So we have that one, too, and we can provide our own dealloc
00:40method in our CustomClasses just as we can provide our own init method.
00:44And again, making analogies to other languages, if you're familiar with things like finalizers
00:49or destructors, dealloc is the same idea in Objective-C. It's how we would write some code
00:55that would be run at the end of an object's lifetime. So let's see how to do it.
01:00I'll create a new Xcode project here, it will of course be a Command Line tool, I'll call
01:07it DeallocDemo, Type of Foundation, and I'll select to Use Automatic Reference Counting.
01:12I'll just save that in my documents folder. Once again, add a new class to this so that
01:19we have a CustomClass we can work with. So Cocoa > Objective-C Class. I will call this one Player again, and
01:26it's a Subclass of NSObject, very straightforward stuff going on here.
01:31Now jumping into the implementation into Player.m, we already saw that in the Code Snippet Library,
01:38we had a Code Snippet for an Objective-C init method. And this is useful because it saves
01:45us a little typing. All we really need to put in here is some code for our initialization,
01:50and we also have a Code Snippet for a dealloc method.
01:55This however, is less than useful, for two reasons, one: dealloc is a very, very simple
02:02method, it's simply called dealloc, all lowercase, returns void, takes no parameters.
02:08Now the second reason is that the default Code Snippet includes this line here, which is a call to
02:13super dealloc, the dealloc method of our SuperClass, and that won't even work if you have ARC turned
02:19on for your project.
02:21And that's because with Automatic Reference Counting turned on, you aren't allowed to
02:24call dealloc method of any Object yourself. You might occasionally still need to actually
02:29write this dealloc method, but you wouldn't ever call it yourself. You would let the Objective-C
02:35runtime call the dealloc method when it sees fit. If you try and write code that calls
02:40this method, the Compiler will choke. But why? That's the question.
02:44Well, dealloc exists purely for clean up.
02:48Prior to ARC, the main reason you'd write a dealloc method in your class, the main reason
02:53you'd need one is that your class contained other Objects or being instantiated possibly
02:58in your initializer, but could have been anywhere else in your code. And what you needed to
03:03do is make sure that those objects were released, and if there wasn't a natural place to put
03:07any release code, you'd write your dealloc method and in that release all those internal objects.
03:14And then, again, this is prior to ARC, the standard technique was that after you'd run
03:19dealloc in your Object, you'd call the dealloc on the super class to let it do whatever it needed to.
03:24Well, the thing is if you have ARC turned on, you don't need to release anymore.
03:29In fact, you can't release anymore, you are not allowed to write that code, and if all
03:34that you're dealloc method was doing was calling super dealloc, well, that happens anyway.
03:38We don't need the method at all. So a lot of dealloc Methods that we would have written
03:43prior to ARC just don't get written using Automatic Reference Counting.
03:48But make no mistake, dealloc still exists for every class. We can write a dealloc method, but you let
03:56the Objective-C runtime take care of calling you, you don't call it yourself. So the question
04:01is why would we still need dealloc at all? Well, it is much less required if you use ARC.
04:07And for this level--of course--that we're doing here some basic Command Line Tools, we really
04:11don't need dealloc Methods. The main requirement for using a dealloc is in more complex applications
04:17if your Object is holding onto some kind of resource. Here is an example of this idea.
04:23Let's say in my initializer what we have done is open a connection to a database or file,
04:29so I am just going to add a comment that represents that. Well, we might then need a dealloc method
04:35added to this class to make sure that the connection is properly closed before this
04:41object is destroyed.
04:45So this kind of thing can often be required for connections to Databases or holding open
04:50file connections on the local machine. But if you're using ARC, it's not necessary just
04:54to clean up your own objects, because those should be released automatically.
04:59So that's the kind of reason you'd write a dealloc method, for cleanup code that needs to happen.
05:04But you just let this dealloc method be called when Objective-C reclaims the Object.
05:09And as I mentioned, prior to ARC, you'd see a lot of this kind of call, that in your dealloc
05:14method, you'd make a call to super dealloc.
05:17But you'll only now see that in the non-ARC code, and with ARC turned on, all actual calls
05:22to dealloc up and down the object hierarchy will be done automatically. You can write
05:27a dealloc method, and it will be called at the right time, but you can't explicitly call it yourself.
Collapse this transcript
8. Collections
Working with C-style arrays
00:00One thing we haven't talked about up to this point are arrays, the ability to
00:04have a variable that holds multiple values at the same time.
00:08Now in Objective-C we have the old regular C style way of doing arrays and we
00:13will also have some new classes to work with.
00:16Let's start off with these C style ones first.
00:18Now as we've seen creating a variable that holds say a single integer very easy,
00:24give it the type, give it the name.
00:25that carves out the area of space that can hold an integer and then we just use
00:29that name to access that integer and change it and do whatever we want with it.
00:34Now to create an array of integers meaning we've got one variable that holds
00:40multiple values I start off by doing exactly the same thing, use the type and
00:44then the name but before the semi-colon, I'm in the use of square brackets to
00:50say how many should this hold.
00:52In this case I'm saying five.
00:54so what it will go through is carve out five integers for me and because I'll
00:59need a way to get to each one it's going to give them each and index.
01:04Now in C and Objective-C our arrays are zero-based.
01:08So if we have five elements that will be element 0, 1, 2, 3 and 4.
01:13now this use of the square brackets is nothing to do with Objective-C it's not
01:18about doing the messages the method calls it's just the array accessor.
01:24It's what I used to create the array and it's what I use to access
01:28each individual part.
01:29So I'd say multiple values square bracket zero to access element zero square
01:33brackets one want to access elements one and so on.
01:38Switching over to x code where I have exactly that same code here you imagine it
01:42can get a little tedious to start typing all the individual pieces out.
01:46There is a lot of repetition going on.
01:48So while we could do that way there is also a shortcut if I want to create this
01:54array and initialize all the elements in it I can use curly braces and inside
02:00those curly braces give it all the different values separated by commas let's
02:05say 50, 60, 70, 80, 90.
02:11These are integers so they don't need to be in double quotes or anything like that.
02:15Just to prove that this works we will write out an NSLog message and I'll say
02:20the Value at the third element is and we use the same accessor to just grab
02:28then take a look at it. multipleValues 2.
02:30Two would be the third element, 0, 1, 2.
02:38Say that, run it and we would expect to see 17 being output as our message.
02:43nothing particularly remarkable going on.
02:46In fact if I am providing all the initializers here using these curly braces I
02:52technically don't need this number and you could actually leave it and it would
02:56work exactly the same way creating an array of integers that has five elements.
03:02If I conflicted with myself that I said the array should have five elements and
03:06then I tried to provide six, I'm likely to get a warning here that says you got
03:10Excess elements in your array initializer.
03:12So let's get that one back.
03:15Moving on little bit, you can do this also not just with instant floats and
03:19charts, but you can do it with objects as well.
03:22We are using Objective-C object but we're making a C style array of them.
03:27So here I am going to go do NSString and we start off by creating something very
03:31similar to an individual element.
03:33I will just call it myStringArray.
03:36It's a pointer of course but again I just used the square brackets and say that
03:40with this one I want five or 10 or 15 or 5000 and now I have an array called
03:46myStringArray that can hold five NSString object not technically of course what
03:52it's holding is five pointers to NSString objects.
03:56The NSStrings don't exist so it used the same way instead of going through it,
04:01myStringArray position zero and then I would create that string object because
04:07it doesn't exist yet.
04:12So I could use one of the formal ways creating a string object using alloc and
04:18say a initWithCString or initWithFormat, but of course if I am doing an alloc
04:24for this element, I would need to pair it with a release somewhere and that
04:28could be done just quite simply by again using what evers of that element.
04:34release, that would work just fine.
04:39Though that's a pretty tedious way of doing it, so there is the shorthand with
04:43strings as well which say if you're just creating an array at the start of your
04:48program to hold some messages you don't mind if it hangs around for the
04:51lifetime of your program.
04:53So use the opening and closing curly braces and in here I'll use the Helper
04:58method and just type in some values.
05:05Compiling, and it succeeded it is complaining that I'm not using that array
05:09which it's technically true.
05:10So we are about to use one of them in.
05:17No particular surprise here writing out the word third, and bearing in mind
05:23that on line 12 we are creating five NSString objects but we're using the
05:30shortcut helpful way of doing it.
05:31so these would be considered auto released objects.
05:33I wouldn't need to match them with a manual release or auto release call.
05:37Now these are the basic ways of doing C style arrays.
05:41There are three things to be aware of when them one.
05:45One, there is no bounds checking, what does that mean?
05:48Let's say up here where I defined an integer array called multipleValues and I
05:54said equal to five elements.
05:55I could type the code multipleValues 99 equals whatever.
06:02I am trying to access an element that doesn't exist.
06:06Now if I compile this build is actually going to succeed and in fact I could
06:11even run it and it would run through and finish and exit successfully.
06:15But this is an astoundingly bad idea because we're reaching into an area of
06:19memory that we didn't claim properly, so not a good thing so no bounds checking on these.
06:25Second limit fixed size.
06:28we're creating these arrays at a particular side both of these cases were five.
06:34I cannot come to say to my string array and then say oh I want to add another
06:38element or remove another element.
06:41Once it's created, it's fixed and third, can't make types.
06:48I'm creating an array of integers, an array of NSString pointers.
06:52I am not creating an array that can hold an integer and a float and an NSString
06:58and a date and a piece of video.
07:00So while they are simple to create in their awesome limitations and those
07:03limitations are fixed by the classes that have been provided for us in the extra
07:08frameworks like the foundation framework and will see that next.
Collapse this transcript
Working with Objective-C array objects
00:00So let's see what Objective-C brings to the table as regards arrays.
00:05Well, if we know there when we were working with strings, we look for NSString
00:09and when we are working with dates, we look for NSDate, even I might make the
00:12assumption to look for an NSArray class and indeed I have one.
00:16It's a regular class in Objective-C which means we need an object pointer for
00:20it, so I am going to create one called myArray and set it equal to.
00:24Now how do I make this?
00:25There is a couple of different ways.
00:27One thing you could do is we could go along the road of using the usual
00:31class name alloc init.
00:33We are very unlikely just to say init because NSArrays want to be creative
00:38with their contents.
00:40So the most common initializer is init with objects.
00:44I am just going to give it the simplest way of giving in a couple of objects
00:49here, which is two in-line created NSStrings and then there's a comma and then
00:55the word nil, what's that all about?
00:57Well, we didn't say how long the array was explicitly, there are no little
01:02square brackets with the number two in them.
01:04So what it's going to do is just keep on adding new objects to this array
01:08till it hits the word nil, nil needs to be the last thing whenever we're creating this.
01:13This will give me an array.
01:15I have used the magic word alloc so I would need to pair this with a release
01:20statement, although if I wanted to there is a shortcut method to create an auto
01:25released array which would be instead of using the word alloc, I just make a
01:29direct call to NSArray, arrayWithObjects instead of initWithObjects.
01:36I didn't use any of the knock words here, no new, no alloc, no copy, no retain.
01:41So I wouldn't need to call release on this.
01:43You'll begin to see this kind of example used all over the place, arrays,
01:48strings, dates all use it.
01:50Then to improve it's actually working, I am going to change my log message here
01:55to spit out something.
01:58The second element is.
01:59What we are expecting back?
02:03We're expecting an object, so my placeholder will be percent sign at sign.
02:07Then how do I get to that element?
02:09Well, you might think that we could use something like myArray1, but that would
02:15be the C style way of doing it.
02:17That's not going to work here.
02:19We're in Objective-C.
02:20We're calling methods for everything.
02:22So what I do is I am doing the myArray and probably the single most common
02:29method for working with arrays which is objectAtIndex.
02:34This method will take an argument of an integer, in this case I'll put in one to
02:38get that second element, and it will return that object.
02:43Save it, run it and not surprisingly we should get out the second element is two.
02:49You might not see an awful lot of improvement here, but there is quite a big
02:54difference with working with NSArrays, one thing is I can load it with pretty
02:59much whatever I want.
03:00Let's say I create an NSDate object here.
03:03I'll call it myDate, and I'll just create it with the full on alloc and init.
03:07Well what I can do, is when I'm creating this array, I can just pass that in
03:13as one of the objects.
03:15We can have strings, we can have dates, we can have videos, we can have anything
03:20added to an NSArray.
03:22All it cares about is that there are objects in it, doesn't care what kind of objects.
03:27Now this leads us to an interesting thing here.
03:31I've created this NSDate called myDate on line nine and I am using alloc and init.
03:37So I need to pair that with a release.
03:40Well interestingly what I could actually do here is immediately call release on
03:48myDate once I've added it to the array.
03:50Now you might think, well hang on a second, what happens if the date object
03:55goes away and then I try and access that element of the array, well, we're okay
03:59because what actually happens when we add it to the NSArray is the NSArray
04:04gives it a retain call.
04:06It will take care of keeping hold of that.
04:09What I'm allowed to now say is that I'm done in myCode with it, I'm releasing it.
04:13While you can of course use your Option+click to jump in and see that there are
04:18a whole bunch of other methods, you'll find that arrayWithObjects or
04:22initWithObjects and the objectInIndex very much the common terms to work with
04:27your array and the array elements.
04:29So browse through the documentation at some point and see what else seems useful for you.
04:34However, here is the biggest issue you're likely to run into.
04:38An NSArray object is immutable, immutable meaning unchangeable.
04:45Once it's created you cannot add new objects to it, you cannot remove objects from it.
04:51It's a fixed size.
04:53Now I'd already said that was a limitation of the regular C style arrays and I
04:57thought we were going to fix this. Well we can.
05:00See a lot of the time an immutable array is just fine.
05:04You know how big it needs to be, you create it with the data that it needs, but
05:07sometimes you need something a bit more flexible and we can do that too.
05:11What I can do is change this declaration from NSArray to NSMutableArray and over
05:21here change my initialization to NSMutableArray, array with objects.
05:28NSMutableArray is a subclass of NSArray which means it can do all the things
05:34NSArray can, but it's got a little bit extra functionality too.
05:39So what I can do after this thing has been created is I can call a method of
05:44myArray called addObject.
05:48Now this doesn't exist if myArray was an NSArray, but it exists when it's a mutable array.
05:56So if you need that flexibility, this is how you get it.
05:59Not only that, but you have the ability to remove object.
06:05Now there is a few different ways of doing it.
06:07One of the most common ones would be removeObjectAtIndex.
06:10I am going to pass in the number one.
06:12Now what that should do is remove the NSString two from the array.
06:19That will collapse that element and the myDate object should now move into
06:24that second position.
06:26Well down on line 19 I have an NSLog that's going to write up whatever is at
06:29that second position and I'll add one more piece to it that just says the array
06:34count is, so we can find out the length of it.
06:37This is going to be an integer which does mean that the first thing after
06:43the comma needs to be myArray and there is a count method comma myArray objectAtIndex.
06:49If I quickly run that it's telling me that the array count is three which is
07:00what I'd expect now.
07:01It was three then I added one, then I removed one and the second element is and
07:06we are getting the output of the date.
07:08Now it is giving me a complaint here, Conversion specifies type int, but the
07:17argument has type NSUInteger also known as unsigned long and if you notice here
07:24what it's doing is it's giving me a fix it to say that it suggests that I
07:28replace that placeholder %i with %lu which is for an unsigned long integer.
07:34That's simply because that is how the count method is defined in the
07:38NSMutabeArray object and in the NSArray object.
07:42I'll accept that, fix it.
07:43As we saw it works without it, but this will now no longer give me warnings.
07:47While we can get a bit more complex with other more specialized classes when we
07:52are working with collections of objects, you are likely to see NSArray and
07:56NSMutableArray used all over the place.
Collapse this transcript
Using dictionaries
00:01Time-and-time again we'll work with C style arrays, we'll work with NSArrays
00:05and NSMutable arrays and they are great for working with collections of objects
00:10as long as you're happy by accessing each of those elements using that
00:13zero-based array index.
00:15Well, what if you're not?
00:17Well, we also have another object.
00:19We can use this called a dictionary.
00:21And the idea of a dictionary in Objective-C is like the idea of a dictionary on your bookshelf.
00:26The whole point of a dictionary is that you have a word and a description.
00:30The words are the key to the right place in the dictionary, but you're using the
00:35words to look up the description.
00:36That doesn't mean we are actually writing a dictionary.
00:40a set of descriptions in terms in our program, although we could.
00:44What you'll find is that a dictionary object could be commonly used for things
00:47like State or Country LookUp tables where we have common abbreviations, and we
00:53can use those as the key to the actual entry, in this case AZ goes to Arizona,
00:59CA to California and so on.
01:01You could use them as simple lookups for product lists, because it's up to
01:06you what that key is.
01:09Now usually it's a string but it could be just say a number, and while it's
01:14easy to think of the dictionary entry itself being another string, or it could be any object.
01:20So we could have the word startdate look up in NSDate for example.
01:24But we are imposing our own structure on how these individual entries are looked up.
01:31So let me show you how to write one.
01:33In another simple project here, just a command-line foundation tool, I am going
01:41to type-in NSD, I have got NSDictionary.
01:43If you occasionally try to do some of the code sense and you don't see
01:46anything appear, do make sure that you've done a recent build, because
01:50sometimes Xcode likes to have a build being done before it'll present you with
01:54all the code sense.
01:55So I will make an NSDictionary.
01:57It is of course a pointer type, I will call it states, and what I am going to do
02:01is I am going to use the method of NSDictionary called
02:06DictionaryWithObjectsAndKeys.
02:09This will give me an Autoreleased NSDictionary.
02:12If I want a more manual control, I'd say NSDictionary alloc init with objects
02:18and keys, but this one will do just fine.
02:20Now notice the phrasing here.
02:22DictionaryWithObjectsAndKeys, unlike an array we do have to provide two pieces
02:28of information for each slot.
02:31It's also telling us what order they need to be in, which is object then key,
02:35not key then object.
02:37The object would be Arizona in NSString, the key would be AZ. Let me do a
02:44couple more of these.
02:45I am going to split it on another the line just to make it a little bit more readable.
02:51I'll just add a few right now, and then like working with an array, we indicate
02:56that we are done by the word nil, close the square brackets and we are done.
03:00Now the whole reason for creating a dictionary is that we are going to access it
03:05at some point in the future.
03:06So let's imagine that a little later on in our program we have a State
03:11abbreviation and we need to use it to lookup the right slot in the dictionary.
03:15So I will just create an NSString object and hold the State.
03:19I don't have to do it this way.
03:20I could have just used a literal but this would be fine, I will call it
03:23someState and set it equal to AZ.
03:26And then we will do an NSLog message.
03:30I will have two placeholders, percent sign at sign, is for %@, first placeholder
03:39will be filled by the someState abbreviation, and the second one what we are
03:43going to do is use the State's dictionary and use the method called
03:49objectForKey, and here is where I pass it the key, which I have someState.
03:54It's in NSString and that's fine. Save that, run it.
04:01As we see here AZ is for Arizona, and no particular surprise here feed in CA,
04:08CA is for California.
04:11The thing is, we don't have to know what position these are in, in the dictionary.
04:16Now even though the few entries that I put in, I did in alphabetical order you
04:21don't have to do that.
04:23Dictionary is quite capable of looking up these different values.
04:26You don't have to impose your own thought structure on that.
04:30It's fine if it was the other way around or even all mixed up.
04:33Now just like working with NSArray, the NSDictionary is immutable. It's unchangeable.
04:40After it has been created you cannot add a new entry to it, but also just
04:46like the NSArray, and you might know where I'm going with this, there is
04:49another version of it, called the NSMutableDictionary and we just add the
04:53word Mutable in here, NSMutableDictionary inherits from NSDictionary which
04:59means it has all the same methods.
05:01It just has a few more.
05:04As the example, the few more includes a method called setObject: forKey.
05:13This is how we add a new object into the NSMutableDictionary.
05:19So in this case, I'll just say this one as Florida forkey FL.
05:22And not surprisingly, if I just feed an FL for it, and run that, we will get FL as for Florida.
05:32Now when you stop working with dictionaries, you'll find it quite common to end
05:39up with quite large ones, and sometimes it can be useful to automatically to be
05:44able to loop through all of them without knowing exactly how many there are.
05:47Luckily, we can do that, the something called fast enumeration that's supported
05:52in Objective-C and we will go through that next.
Collapse this transcript
Fast enumeration
00:00Back when we were talking about loops, I mentioned there was a kind of looping
00:04called Fast Enumeration that we would see a little later on.
00:07And now is the time.
00:08So we're familiar with the idea of the for loop.
00:12Setting up a block of code to execute and then having those three different pieces.
00:16the initializer, the condition, and the incrementer on the top.
00:20And they're great but they don't really help you, say, go automatically
00:24through a collection.
00:25Well, what we're going to use instead is a variant of the for loop.
00:30Except we're going to say, and this is a little bit pseudo-coding, just going
00:33to have a little phrase here that says for each element in my collection I
00:38would like to repeat this loop whether that collection has 5 elements in it or 500 or 5000.
00:43So we have to figure out how do we say this.
00:48So let's imagine that I've got an NSArray object and it's just got strings in it.
00:53Could be 5 things and it could be 500, I don't know.
00:56What I want to do is just say I want to loop through every string in myArray,
01:03and I'll say it this way.
01:04First, I'll name the type of the individual element and then I'll give it a temporary name.
01:08in this case x. Then the word, in, and that's really the only other keyword
01:13here, and then the name of my NSArray.
01:15It works with the Objective-C collections like NSArray, MutableArray,
01:20NSDictionary, and so on.
01:21What that means is that it'll automatically loop through every element
01:25temporarily for each part of the loop giving it the name, in this case, x.
01:30So the first time through x will be carpenteria.
01:32Second time through x will be camarillo.
01:35third time through, it will be ventura.
01:37fourth time, Oxnard.
01:38fifth time, santa barbara.
01:41So let's see it at work in a real example.
01:43This was the MutableDictionary that I created in the last movie.
01:47It's just got a bunch of states loaded into it.
01:50And while I had written a couple of lines to directly access one part of it,
01:54what I would like to do here is just write out a message with every element in that array.
02:00So what I am going to do is get rid of that.
02:03I am just going to type the word, for.
02:05And when we do on a Mutable Dictionary or just a Dictionary, what we're
02:10interested in is the keys, and that's what Fast Enumeration will give us here.
02:14It'll give us all the keys.
02:16So I have to say well, what are my keys?
02:18My keys are NSStrings.
02:19So I am going to say it NSString, and then I have to give it a temporary name
02:25for each iteration of the loop.
02:26I could call it key or stateAbbreviation. it doesn't matter.
02:34Then the word, in, and then the name of the collection which, in this case, is states.
02:41That term stateAbbrev is just something I made up.
02:44It's only going to exist for the lifetime of the loop.
02:47I am going to then copy in my NSLog message that I had written earlier.
02:53But instead of having some state that doesn't exist anymore, I'll just say well,
02:56what I am interested in is that stateAbbrev.
03:00And now it'll also be used as the key to access the object there.
03:05This is Fast Enumeration.
03:08The for loop doesn't know how big it is.
03:10It's not looking up the count of this MutableDictionary.
03:13It doesn't matter whether there were 50 things or 5000 things.
03:16it's going to go through all of them.
03:18We save it, we run it and not surprisingly, it goes through all the entries in
03:24that dictionary and writes them out.
Collapse this transcript
9. File Management
Introduction to file management in Objective-C
00:00No language will be complete without some discussion of reading and writing
00:03files to the file system.
00:05And although we do have the very low level C way of doing things, I'm not going
00:09to be touching that at all because in Objective-C we have these great classes
00:15that help us save files, read files, copy them, read through directories.
00:20And although there are quite a few of them, the heart of everything is a class
00:25called NSFileManager.
00:32We can get this file just by simply doing an alloc init on it.
00:40Then what we instantly have are methods for say copying, copying item a path or to URL.
00:48If I type Move I can see I can move files.
00:52There is a fileExistsAtPath that returns a Boolean, does this file
00:59actually exist or not?
01:03Typing att I can let the Code Sense show me that there are ways of getting
01:07attributes of the item at a particular path.
01:11We can remove items as well.
01:13So it really does allow us to do quite a lot with it.
01:16But before we do any of that, what I'm going to start off with is a path to something.
01:21If I jump over to Finder I am just going to show you that I've got a simple text
01:26file sitting in my own home directory here.
01:29There is nothing remarkable about this one.
01:31If I look at Get Info, I can see it's just text.txt.
01:35I'm hiding the extension right now, but that's fine.
01:37So I'm going to create an NSString just to hold that path.
01:47Now although I'm not a big fan of having paths hard-coded into your programs,
01:52for our sakes here this is a useful enough way of doing it and then I am going
01:57to do some operations with that.
01:58Well, first off, I better call and find out does this actual file exist or at
02:03least does the File Manager think it exists?
02:05So I am going to write the body of my if statement here and inside the
02:10parentheses I will call File Manager and I am going to ask fileExistsAtPath.
02:17There's a separate option that allows me to ask if this is a directory, but I
02:24just need the first one here.
02:26Just hit Return, and I'll be passing-in that NSString I called, called Path.
02:31Now, this is a method that returns a Boolean.
02:35So while I could put == YES, I don't really need to because the method itself is
02:40going to return yes or no.
02:41Well, we'll start off with something simple just an NSLog message.
02:45yes, it exists or no, it doesn't.
02:49Save that, run, and we're getting no.
02:55It doesn't mainly because I spelled it incorrectly.
03:02It's text.txt, so just make that change, run it again, and then we're
03:07getting yes, it exists.
03:08So I've got a nice little proof that to both my yes and my no work.
03:11Well, that's not really very exciting, so let's do a little more with it.
03:16What I can do is grab the attributes of that file.
03:21As you might imagine there's quite a few different attributes.
03:24So the question is how do I get them?
03:26Well, what's going to happen is getting the attributes is actually going to
03:29return an NSDictionary, and luckily we've already done a little bit of work
03:34through with the NSDictionary.
03:35So I am going to call it fileAttributes and set that equal to and use my File
03:43Manager again, and the method that I want is attributesOfItemAtPath.
03:50The path is again my path and then I have a second parameter here called Error.
03:56Let me split that on another line so it's a bit more readable.
03:59So this method takes a second parameter which is basically handing over an error
04:04object, so if there's an error, it can fill it and then pass it back.
04:07I am just going to set that to Nil, because we really don't need it right now.
04:11So that should come back with an NSDictionary full of attributes about that file
04:16and we want to prove it.
04:18So I'm going to do some fast enumeration through that dictionary and print them all out.
04:25What I've done here is very similar to the code we had in our fast
04:28enumeration section which is simply looping through all the keys, and then
04:34I'm writing out what each key is and what the object for that key is in that
04:38Attributes dictionary.
04:40So let's run this, re-run that, I am going to drag this debug window a
04:44little wider and we can start to see that we're getting a whole bunch of
04:47different attributes.
04:48I am going to hide my Navigator just to give us a bit more room, make it a bit
04:52more readable here, file owner account IDs, file size, file system number, file
04:58type, extended attributes, still there is a bunch of stuff there that we can get to.
05:03Again, I am not going to do anything with it, but as you can see, you really can
05:06start to drill down into very particular pieces of that information.
05:11So after getting the attributes I am going to do one more thing to it which is
05:14basically change its name.
05:16The way that we do that is using again the File Manager, File Manager is pretty
05:21much the way we do just about every file operation.
05:24We're going to say moveItemAtPath.
05:29We'll give the first path that we've been using all along, hit Tab, jump across.
05:35Now, the next part of the method which is toPath, I can just give it a path literal here.
05:40Again wouldn't typically do this in real code, but for our purposes it's just fine.
05:45Call it newname.txt, and then I'm going to pass-in Nil for the error again,
05:52save that and run it.
05:55We spit out all the attributes but I should hope if I jump over to my Finder
06:00that yes, I now have newname.txt.
06:03And of course if I click back into my program, cleared the debug area and just
06:08ran it again, all that it would expect to see was the message no, it doesn't
06:13because that file doesn't have this original path anymore.
06:19The last thing that I should do of course being a good Objective-C programmer
06:22is find anything that I manually alloced and inited which was the NSFileManager and release it.
06:29So as you can see it's just that one class really does drive a lot of
06:34behavior about working with files and you can also work with the directories the same way.
06:39What we haven't yet done is start reading or writing.
06:42So we'll get to that next.
Collapse this transcript
Working with paths and URLs
00:00The first few times we think about reading or writing files in Objective-C we
00:04tend to think in terms of file paths.
00:06a simple string of text, something like this.
00:09Now this is okay to get us started but I'm about to tell you that we're going
00:12to stop doing it this way, yes we will still see file paths as good old
00:18NSStrings but from now on we're going to add one more step to every path that we work with.
00:23We are going to turn this NSString object into an NSURL object.
00:29Now for a lot of people when they think about URLs they just think the address
00:33of a website but for us it's much more than that.
00:36A URL after all is the location all of a resource and it's a great way to work with files.
00:43Even if we look at a simple web address like this, there is quite a lot going on
00:47in the URL there is this scheme right at the front.
00:51There is the domain, the location of this, and those two separated by the colon
00:56forward slash, forward slash.
00:57There is the path that could also be a query string or fragment ID.
01:03Now the scheme could be a HTTP could be HTTPS, could be FTP or it could be file
01:08which is what we're interested in here.
01:11We still need be :// then we have the equivalent on the domain.
01:17Now we could be using the address of another machine or we could be using a
01:20local host to represent our own machine and after that we would have the
01:25equivalent of what we think a normal file path would be.
01:28Forwards slash up to the top, down into users into the Simon folder into file.txt.
01:35now we could actually leave the domain out by default that would assume that
01:39we're on the local machine.
01:41Now if we do that we're just pulling the name of the domain out and we would
01:45collapse the URL down which can look a little odd because it has a three forward
01:50slashes but this would be considered a valid file URL.
01:56And if your app needs to work with paths to anything for files resources web
02:00services, websites, you should be using object of the NSURL class not just using
02:05a string with that path in it.
02:07Now the question is why?
02:10Well it could just say because Apple said so and they do, Apple are on record of
02:14saying URLs are preferred over paths it is a best practice but more than that
02:19NSURL objects are faster and Apple wrote a lot of code in Snow Leopard to
02:24optimize URL-based operations and they are typically more efficient than their
02:28path-based equivalents.
02:29Sure you're not going to notice this in a small program but as your programs get
02:33more complex it can add up.
02:35two, they are better for catching errors.
02:38It's easy to make a mistake when you're writing a path as a string but an NSURL
02:43won't allow itself to be created unless the URL is well formed meaning it has
02:49all the pieces it needs, nothing is missing.
02:52Three they are more powerful and what I mean by that is there are more and
02:56more classes in Cocoa particular the newer ones that only want to work with an NSURL object.
03:03Now sure there are still a bunch of classes in Cocoa that can work with a file
03:08path as a string and I will be the case for a long time.
03:11Even the NSString object has string with contents of file that can just take a file path.
03:17There is an NSImage class that has init with contents of file that will
03:21just take a file path.
03:23But these classes also work with URLs where we had string with contents of
03:30file we have the string with contents of URL where we have init with contents of file.
03:35We have init with contents of URL.
03:38This is very commonly what you'll find but more importantly there are some very
03:42powerful classes things like NSDocument that won't accept file paths of strings
03:46they only accept URLs.
03:49So the document, the audio-video player item, the NSURLRequest these expect
03:55and want these NSURL.
03:58So we need to get comfortable creating and working with these NSURL objects and
04:02luckily they're pretty easy to make.
04:05So I am looking here at the code that I created in the last section the one that
04:11just opened up a file at a file path and looked at some of the attributes and
04:15then moved it around.
04:16So on line 10, I do have a typical string-based path and what I am going to do
04:22is convert this into an NSURL object.
04:25NSURL is a class in the foundation framework so we don't need to worry about
04:30linking to some other framework it's going to be there in any project, we make
04:34along with all the other super common classes.
04:37It's written all caps which might look a little unusual but after all URL is
04:41an abbreviation and we don't want to have to write NS Uniform Resource Locator all the time.
04:46So are going to say NSURL and I'll call it my myURL.
04:51So how do you create it, well typically you won't do an alloc in the init call,
04:55you going to use a different method because like strings you want to create a
04:59URL with some value.
05:02Now if I start typing in the name of the class and see what class methods are
05:07available I might start looking at some and I see that I've got a URL with
05:11string and that looks likely but it's not going to work.
05:15You see if I use the URL with string method and just pass in what I can think of
05:20is a string-based path it's going to fail.
05:23So what it's expecting here is a well formed URL which means it would expect to
05:29have the scheme of file:///.
05:34And if I just passed in for example that string called path this is going to fail.
05:41It's not well formed.
05:42However what there is is an alternative which if I do have a normal file path I
05:47can call NSURL fileURLWithPath and that should do the trick.
05:55Now I don't see an alloc or an init here so I can assume that this object
06:00will be auto released.
06:01But again if you're starting to explore them you really want to do one of the
06:05good old Option+clicks and jump to the class reference and just get familiar
06:09with the different ways that an NSURL can be created.
06:13Once I've got one, then what?
06:15Well this is actually a pretty good example because if I start to come down to
06:19where the file manager is interacting with things I'll see that there are quite
06:26a few path-based methods.
06:26fileExistsPath attributesOfItemAtPath and because the NS file manager is an
06:31older class there are a lot of path-based method still there but I could come
06:35down for example here where we are doing the moveItemAtPath and if I type in
06:40moveItemAtPath I can see that I have the exact equivalent as moveItemAtURL
06:46and this would be the preferred way of doing it.
06:51In here I will put in my URL again I have got two URL so I would need to create
06:55another I am not actually going to do that right now but you get the picture.
06:59The whole point of creating these NSURLs is because you are going to use
07:04them somewhere else.
07:05they are a means to an end.
07:06You will be using them to read in contents of files.
07:10You will be using them to create other objects, but as you see they are pretty
07:14easy to create and this is the best practice going forward.
Collapse this transcript
Reading and writing strings
00:00Although, NSFileManager will be the class you use if you are wanting to work
00:04with files and directories in any significant way, we don't actually even have
00:08to go that deep, if all we're wanting to do is say reading the contents of a
00:12file into a string or even go the other way and save the contents of a string as a file.
00:17So I've got another simple project here, on line 9 I've just, to save us some
00:22time written the file URL here that's pointing to an existing file.
00:26And what I'm going to do is create a new NSString object, and instead of giving
00:32it an explicit value, I'm going to call the method of NSString, called
00:37StringWithContentsOfURL.
00:38There are a couple of different choices, the difference here is one has a
00:43second parameter called encoding and the other one has a second parameter
00:47called usedEncoding.
00:49I'm picking the first one because I'm going to tell it that as far as I'm aware
00:54it was encoded standard ASCII UTF-8 equivalent.
00:58The first thing I have to give it is the fileURL that I created on the previous
01:02line, then hit Tab, and the encoding here is actually a built-in enumeration.
01:08We haven't used this one yet, but what I'm going to type is NS and as I start
01:13typing, I'll start type UTF and it gives me a variety of different Unicode Text
01:19Format encoding options.
01:21I'm picking the UTF8StringEncoding, the most basic one here.
01:26And then we've got another error parameter here, I'm just going to send it Nil.
01:32So in line 11 we should go out, find the contents of that file and read that
01:37into that string called Text.
01:39To prove it let's write out a message.
01:42Oops! Got my % sign and @ sign around the wrong way there, and run it.
02:00Nothing shocking, but apparently the contents of that file say This is a simple text file.
02:05What I'm going to do in the next step is change it and save it back.
02:10Now I can't actually change the NSString because that is an immutable string, so
02:15what I'll do on line 11 is just change it to an NSMutableString.
02:21Leaving everything else the same except the name of the class, Mutable String
02:26inherits from NSString, so we have all the same options.
02:29But what that allows me to do is say I've got this Mutable String called text
02:33which now has a nice method called appendString.
02:41So we're changing the contents of that Mutable String in memory and on the next
02:45line I'm going to save it back to that original file address.
02:50Again, it's just a method of the NSString object.
02:53I type in wr and it's giving me the writeToURL, I'm going to use the same one
02:59that we read in with.
03:00Well the next parameter, the Boolean for atomically means, is if you say Yes,
03:07it will save the file first to a temporary file name to make sure that it can
03:12save all the contents to the hard drive and then when that successfully works, it will rename it.
03:18This is designed to protect you if there are any issues when actually saving to the disk drive.
03:23So I'm going to say YES, why not.
03:26Encoding, I'll do exactly the same encoding as we did before, which was the
03:30NSUTF8StringEncoding and I'll leave the error as nil, Save that and run it.
03:39We get the message coming out saying, The contents were:
03:41This is a simple text file.
03:43But if I jump over to Finder and go and find that text file right now here,
03:48it's just been modified right now and I should expect to see a couple of options in here.
03:55It's added the words, here's some more text and even more text, and that's been
03:59successfully saved back from our code.
04:03Now while this is obviously something that you'd use for fairly small files, the
04:09ability for a lot of these Objective-C classes to be able to read and write
04:13their own data can be very, very useful.
04:16It's not just strings but image files, NSDocument files, there is a lot of stuff
04:21that has these possibilities.
04:23If your desire is to actually go deeper into the reading and writing without
04:28actually loading them into a particular object, then looking at the NSData class
04:34and the NSFileHandle is probably what you're after.
Collapse this transcript
Archiving objects
00:00So as we've seen it's pretty simple to use some of these built-in methods to
00:04save data from say an NSString or read data into an NSString.
00:08But what happens when we're working say with our own objects?
00:12What happens if, for example, I've defined an Employee class that holds a few
00:16different pieces of data and what I'd like to be able to do is save objects of
00:21that class to the file system?
00:23Well, I could write a whole bunch of code that breaks apart different things and
00:27saves them all as NSStrings to different files, but that's fairly inconvenient.
00:32So if I want to have this process of taking it to a file, there are a couple of
00:36classes in the Foundation. framework that can help us.
00:40The first class is called NSKeyedArchiver.
00:44What it lets us do is break apart the different pieces of our objects, give them
00:51a key, and then store them in that file.
00:54This process is called encoding.
00:56But if you're going to encode, you almost certainly want to decode.
01:00You want to be able to break it out of a file and reconstitute that object,
01:04and of course you can.
01:06The flipside is the NSKeyedUnarchiver, which can read that file and then break
01:11it apart and reconstitute, rebuild the Employee object, and that is the
01:15process of decoding.
01:17So let's see how we do it.
01:19Jumping over into Xcode, I've got a very simple project set up here.
01:24I've created a very straightforward class called Employee.
01:28It's about as simple as it gets.
01:30It has two instance variables.
01:32an NSString pointer for name and an integer for grade.
01:36I've added the two lines to create the properties for that.
01:40Then over here in the implementation I've got the synthesize statement for that.
01:44The only other thing that I have in here is a simple description method that
01:49creates a string with information about that object, and that's not important.
01:54Jumping over to main.m, all I have here is on Line 9 I am instantiating a new
02:00instance of that Employee class called bob, and then I am calling two of the
02:04accessor methods to set his name and set the grade.
02:07On Line 13 I write out the Details.
02:10So there is nothing happening right now as regards archiving this.
02:15We're going to add all of it.
02:16What I want to do is somewhere after that message I want to be able to save that
02:21Employee and save it to the file system.
02:24So what do I need to do?
02:25Well, to support this whole archiving process what I need to do is add two
02:31methods into my implementation.
02:33We'll take it one by one right now.
02:35I am going to support the process of encoding and I need to add a method.
02:40It's going to be an instance method because it works on the individual objects,
02:43and it's called encodeWithCoder.
02:47Now, this is not my own made up name.
02:50It's very important that you use exactly this name, because this is the method
02:55that the KeyedArchiver is going to be looking for.
02:59This encodeWithCoder method takes one parameter.
03:03It's an NSCoder pointer and I'll call it coder.
03:08It's the only part that's not really important here.
03:11When we choose to archive this object, encodeWithCoder will be called.
03:17So we have to add a line of code that says yes, I want to encode the name,
03:20and, yes, I want to encode the grade, or whatever other instance variables or properties we had.
03:26I am going to call a method on the coder parameter that was passed in
03:31called encodeObject.
03:33In this case I am encoding name, which is an NSString. That's the object.
03:37There is a second part called forKey.
03:41Now really what you just do here is kind of give it your own name, give it your own id here.
03:48I'll call it EMPname for employee name.
03:51The only reason that we're doing this is that on the other side of this I'm
03:56going to be given a succession of values and I need to have a key for each one
04:01to make sure that I get them out the right way.
04:04So it's completely up to you what you want to call it.
04:06Now, next up what we do, and I've only got two variables here, so I call
04:12encodeObject and I'm passing in grade and I'll say forKey, let's called it EMPgrade.
04:21Unfortunately, there is going to be a little bit of a problem with this one.
04:27The issue is that grade is an integer and this is expecting an object.
04:33Although it's a warning, I want to take care of it.
04:35What I am first going to do is I have to wrap grade up in an object, I have to box it.
04:41And there is a suitable one to do this with.
04:43It's called the NSNumber class.
04:46I'll call it gradeBox and just create it by calling the numberWithInt method.
04:53This wraps up grade in an object, and then I pass that object into the
05:00encodeObject method. That will do it.
05:03I click Save. I click Build.
05:06Build has succeeded. Okay, so now what?
05:10Well, back over in main.m, I got a little place where I said I wanted to save this object.
05:15So I'm going to write the code to actually save it.
05:17What we're using is that NSKeyedArchiver, not Unarchiver, but Archiver.
05:24We're going to archive that object.
05:26The way we say it is there is a method called archiveRootObject.
05:30We refer to as the RootObject because of course we could be having an entire
05:34object graph, it could be multiple ones involved, and if you think about it, the
05:37way they kind of are, my Employee object itself contains an NSString object. That's okay.
05:44So the object I want to archive was instantiated up on Line 9.
05:48It's called bob, and then it says toFile.
05:51And here it's actually expecting just a string path.
05:56I'll Save it to Users, under my home directory, and I am going to call this
06:02bob.plist, because by default it will save as a Property List file.
06:07We'll take a look at that in just a moment to see what that means.
06:10I am going to Save that, click Build, and then Run it.
06:18It spits out the log message.
06:19There is no message coming back from the archive, but let's go and find out if it worked.
06:22I am going to jump over to my Finder, and I do see that at my home folder here I
06:27do have bob.plist that just got created.
06:30This is a Property List file.
06:34I can actually open it up with Xcode and take a look.
06:38What it's doing and this is what the KeyedArchiver does in conjunction with the
06:42coder is break this down into the tiniest little pieces.
06:46It's a very controlled, very structured, way of doing this.
06:50So it includes not just the data itself such as the Number and the String of Bob
06:55Jones, but what is this object?
06:57Well, it's an Employee.
06:58What does it inherit from?
06:59It inherits from NSObject, all of that kind of stuff.
07:02So it is rather deep.
07:06However, the flipside is, no real point archiving something if you're not
07:10going to unarchive it.
07:12No, that doesn't happen automatically, what I'm going to have to do is jump back
07:16over into my implementation and I am going to add the ability to decode this.
07:24This is a method that returns an id because it's returning an object.
07:28It's basically an initialization method, which makes sense if you think about it.
07:31So it's not decodeWithCoder.
07:33Its initWithCoder, because if this ever happens it will happen on that
07:39first initialization.
07:42Like the previous method it's using the NSCoder object to reconstitute this, and
07:48what I'm doing is the flipside of this.
07:50So I need to set my name instance variable equal to on the way out I called
07:56coder encodeObjectForKey.
07:59This time I'm calling coder decodeObjectForKey.
08:05The keys that I'm passing are just the ones that I defined on previous lines,
08:09say in this case on Line 8.
08:11So it will say EMPname.
08:12Next, I want to get grade back out, although that is going to be an NSNumber, so
08:18I have that in between stage that I need to do to get it out and then decode it.
08:26I'll call it gradeBox again.
08:29coder decodeObjectForKey.
08:33In this case it was EMPgrade.
08:37Then I'll actually set that integer variable by casting out of that NSNumber object.
08:50The NSNumber object actually has a method called integerValue, but that's
08:54returning an NSInteger object.
08:57So this is the only way that I am going to do it that won't give me any warnings.
09:01The last thing I need, because this does need to return an id is I am going to return myself.
09:08Build, Build succeeded.
09:10I am going to jump back over to main, and well, let's prove it.
09:14I think the best way to do this would be after we've archived it off, I'm going
09:19to now create a new Employee.
09:22This one can be called fred, and I'm going to reconstitute fred from
09:27the bob.plist file.
09:29The way that I do is I just call NSKeyedUnarchiver, and the method is
09:40unarchiveObjectWithFile.
09:45Obviously in this case it has to be the same path that I saved it to.
09:49Just going to give myself a bit more room here.
09:53And just to prove that worked I really need to write out an NSLog message that
09:58says The new object is %@, fred description.
10:09If you remember I had written a description method in my implementation.
10:12I'm going to talk about that in just a second.
10:14I'm going to Save that and Run it.
10:16What we see is we're outputting the first message just before we save it and
10:20then we're reading it back in, we're reconstituting that new object, and it has
10:25got all the same data as the previous one.
10:28Again, a very simple example here, but the process is exactly the same even if
10:32you have many more instance variables.
10:35Now, the last thing I was going to point out was, I am calling the description
10:39method of these objects here and I really don't need to.
10:42In fact, I just need to pass in that object name. Why is that?
10:48Well, because by default when you use the percent sign, at sign in an NSLog
10:56message or anything, what it's actually doing is looking for the description
11:01method of that object.
11:03That's the default behavior.
11:04So we're using the NSKeyedArchiver here, we're using the NSKeyedUnarchiver.
11:10Simply by adding those two methods.
11:13the encodeWithCoder and initWithCoder, we can start to support the idea of
11:18breaking this apart into a plist file.
11:20Now, the last thing to point out is, if you take a look in your Code Snippet
11:24Library, you'll actually find one of the examples here, which is the
11:29initWithCoder is there.
11:31For some reason they have the initWithCoder as a code snippet but they don't
11:34have the encodeWithCoder as a code snippet.
11:36It's not a particularly complex one anyway but just to let you know if you're
11:40looking for a bit of a helper, there is one there.
11:42Now, there is one more thing I need to do before I'm done here, which is that in
11:47our initWithCoder, Line 14 is extracting this new object and assigning it to the
11:53instance variable of name.
11:55Well, that certainly means the coder is just providing me an auto-released
11:59object here, and because it is an object I need to make sure that we are
12:02retaining it so that it doesn't disappear.
12:05So I am going to call name retain.
12:10Now, what you'll see is that you'll often see that quite commonly just written
12:14this way, as a nested call.
12:20But either way we're going to retain it here.
12:23The best idea would be if I need to release it I'll come down here to my dealloc
12:28method to make sure that name has a release call.
12:33I don't need to do that for grade, because grade is just an integer and we don't
12:37bother with any of those things with normal primitive types.
Collapse this transcript
10. More Complex Classes
Inheritance and NSObject
00:01A key idea in object-oriented programming is the idea of inheritance and that is
00:06simply meaning a new class can base itself off another class.
00:10It's another form of code reuse.
00:13We've been using it all along, every time I add a new class in Xcode what
00:17it's going to do when I select this Objective-C class is ask, do I inherit from something?
00:24The question is being phrased here as am I the subclass of another class?
00:28In this case I'm selecting NSObject which is one I'll do most of the time.
00:31There are a few other choices in the dropdown, but the rest of them are to do
00:34with more complicated user interfaces, I don't need that.
00:37So NSObject is just fine.
00:40Click Save, I am now inheriting from NSObject.
00:45Well I'm not alone, virtually everything does inherit from NSObject, NSString,
00:49NSArray, NSDate, they all inherit from NSObject.
00:53Even some of the more complex classes we've been dealing with such as
00:56NSMutableString and mutableArray, well they themselves inherit from NSString and
01:01NSArray which in turn inherit from NSObject.
01:05So inheritance can work up multiple levels.
01:08In fact when you get into more complicated user interfaces and say you're
01:13working with views and buttons you'll find that the NSButton inherits some
01:18NSControl which inherits some NSView, which inherits some NSResponder, which in
01:22turn inherits from NSObject.
01:23Now you are unlikely to create inheritance hierarchies of this complicated,
01:30something that's not really needed in Objective-C by most developers.
01:35So we're primarily concerned with what is our direct superclass and that's
01:40the term that we use.
01:42When we create a new interface for a class, in this case call MyClass, after the
01:46name of the class is the colon and then the name of the superclass.
01:52Just because other object-oriented languages use different terms for the same
01:56concept, you might hear this is also refer to as your base class or your parent class.
02:01We are inheriting from NSObject and because so many things inherit from NSObject
02:07you might often hear this refer to as the root class.
02:10It really is at the base of everything.
02:13Now that inheritance means that your class immediately has every piece of
02:17functionality that NSObject has, plus whatever you decided to add, your new
02:23methods, your new instance variables, your new properties.
02:26It is why immediately after creating a new class without writing any extra code
02:31from it, I could come into my main function, add a line to import the class
02:37header files just so main knows what I'm talking about and then write some code
02:42here to create a new instance of that class.
02:45It's why we immediately have an alloc method, because alloc is defined in NSObject.
02:51It's why we have an init method, because init is in NSObject.
02:56It's why you could call the description method on any object anywhere because
03:00NSObject has a description method.
03:03Now of course there's not much point to creating a new class if you are not
03:07going to add anything to it.
03:09While you can add your own methods in your own properties your own instance
03:13variables to your new class, what you can't do is remove methods you get in a superclass.
03:19So I can decide not to have an init method, though I could choose to make my own version of it.
03:26Now what you might find useful is occasionally doing an Option+click on
03:30NSObject, taking a look at the class reference and actually finding out what are
03:35available methods in this NSObject class, what things might I'd be interested in
03:41providing my own version of?
03:44Well to be honest, there is not that many, I mean you are very unlikely to
03:48create your own version of alloc for example.
03:51The one that's there is perfectly good enough.
03:53In fact the methods that you're most likely to provide your own version of are
03:58the init method and the dealloc method.
04:02In fact those are the ones that conveniently are provided for you as boilerplate
04:08code to provide your own version of them in your own class implementation.
04:12This is what's called overriding, you can override a method in the superclass by
04:18providing your own version of it.
04:20Now it needs two examples here both for the init method beginning on line 14 and
04:25the dealloc method, we can see we have a little bit of code in here and we've
04:29seen this one before, but what's quite common is this call to super.
04:34We have a call to super init on line 16 and then in our dealloc method we have a
04:39line to super dealloc.
04:41This is great for us because what it allows us to do is both provide our own
04:45implementation of init and dealloc and still use the one that's defined in the
04:51superclass in NSObject.
04:53So in the init method on line 16 we first say pass this backup, let NSObject
04:58do whatever it needs to do internally, I don't even need to think about that
05:02and then on line 17 making sure that I exist as an object I'm going to then do
05:07my own extra stuff.
05:08In the dealloc method well before the call to super dealloc, I could then tidy
05:14up anything that I did myself.
05:16Very common patterns to see, you don't need to provide your own version of them,
05:20but this would be the way that you could.
05:22Now to override a method, all you need to do is write a method in your new class
05:29implementation with the same signature as the one in the superclass.
05:34Don't change the parameters, don't change the return type.
05:37The description method is one for example that exists in the
05:41NSObject superclass.
05:42Now you don't need to list any of these overridden methods in your header
05:46file, because your header file already points to NSObject so that compiler
05:51knows that method exists.
05:53Now I am overriding description here.
05:56Description is the method that is called when you use a placeholder in a format
06:01string to write out your object and this just returns an NSString.
06:06This would not be a method where I would need to call the superclass version, so
06:10there is no call to super description, because there is no point.
06:13Now what happens if I don't override it?
06:16Well, let me show you.
06:18So in this current brand-new class I don't have an overridden
06:20description method.
06:21I am going to jump over to my main.m and after the line that instantiates that
06:27object I am just going to output a message that says "The description is %@" as
06:34a placeholder and then say newObject.
06:39This will call the description method of this newObject.
06:43It will see that newObject is an instance of myClass.
06:48It will jump into myClass and look for that implementation say do you have a
06:52description method, in this case I don't.
06:54So what it will then do is kick it up to the superclass which it will see is
06:59NSObject and look for the description method there.
07:03We run this and what we are going to get and this is the default description
07:07method in NSObject that will say the name of the class, not the name of the
07:11object and then the address in memory of this particular object, might be what
07:16you want, but really not very useful.
07:19To provide my own version, I simply jump into my implementation file and in the
07:25body of implementation I am going to write this.
07:27It is an instance method that returns an NSString.
07:33Description, now I don't actually have any instance variables to piece together
07:39which is what I'd usually do here so I will just return interesting message.
07:44You can tell from this that obviously in NSString there is an overridden
07:49description method that returns the contents of the string.
07:52In NSDates there is an overridden description method that returns the date
07:56formatted out as date and time and time zone.
07:59We run this again and now it says okay, you do have an overridden version of
08:03that description so I'll output that one instead.
08:06That's pretty much it.
08:07Once you've overridden the method, it will be used in preference to
08:11the superclass version.
Collapse this transcript
Extending classes with categories
00:01So we use inheritance in every class we deal with, and that might make what I'm
00:06about to say sound a little weird, but in Objective-C inheritance is just not as
00:11big a deal as it is in other languages.
00:13Let me explain what I mean.
00:15See, in most Object-Oriented languages you're concerned about inheritance in at
00:20least two different ways.
00:21One, when you are defining your own unique classes for your app, you inherit
00:26from a typical base class, fine.
00:28We do that too, and it's usually NSObject.
00:30But two, the other way.
00:31See, it's very common in other Object-Oriented languages to need to inherit from
00:37existing specialized classes.
00:39You might have to create your own version of a string class or a subclass, a
00:44collection class, or subclass a built-in UI class, so that you can create your
00:50own extended version of those classes, because the built-in ones don't quite do what you want.
00:55Now, this is the thing we don't need to do in Objective-C.
01:00Sure, we can do it, but we don't need to because of something called categories.
01:04And categories simply allow us to add our own methods to an existing class
01:09without subclassing it.
01:11So simple example, let's say you like the NSString class but you just wish it
01:16had a built-in method to reverse a string or convert a string to Pig Latin or
01:20convertWhiteSpace to underscores.
01:21Well, you could subclass it.
01:25You could create a new class called MyConvertingString that inherits from
01:28NSString and then start to add your new methods to it.
01:32Or you could do it the Objective-C way, which is, you don't bother subclassing
01:38it, you simply use a category that adds those methods to NSString and then in
01:44your application it's as if NSString had had those methods all along.
01:48You don't need to go through your code converting all your NSStrings to your new
01:52converting string object, you just use the new methods.
01:55To create a category, it's a little similar to creating a custom class.
02:00If this is the code to add a new class, we would have the @ sign
02:03interface, MyClass:
02:05NSObject, meaning I inherit from NSObject.
02:09To create a category we do have an interface and an implementation but it
02:14looks more like this.
02:16Our @ sign interface then has the name of the class we want to add to.
02:20in this case NSString.
02:22And then instead of having a colon and the name of our superclass, we use
02:26parenthesis and a category name.
02:28Something descriptive that describes what we're doing this category for.
02:32Now, one big difference is you don't have the opening and closing curly braces,
02:36because using categories you don't add new instance variables.
02:39It's just add new functionality.
02:41So I am going to go ahead and do this.
02:43So I have a good old command line foundation tool here and I have added
02:46precisely two lines to it.
02:48on Line 8 I create a normal NSString and on Line 10 I spit it out.
02:53Let's add a category.
02:53I come up to the File menu and say New File.
02:57Now, we have seen these Objective-C class before, but we also have a built in
03:01template for an Objective-C category that's under the Cocoa section of Mac OS X, click Next.
03:08And instead of asking what is this a subclass of, it's asking what is this a category on?
03:14So what class am I extending?
03:15Well, I want to extend NSString. Click Next.
03:19And then it asks for the name of the category.
03:21Now, you can call it anything you want, but there is a suggested standard
03:26from Apple, just to make your code readable when we're scanning lots of
03:31filenames, the suggestion for categories is you first have the name of the
03:35class that you are extending NSString, then a plus sign, and then whatever is
03:41descriptive for your category name.
03:43Let's say I am creating a category to convert whitespace to underscore.
03:46So I am going to say this is ConvertWhitespace.
03:48And there is nothing magical about this name, you don't have to.
03:53I could name it anything I wanted.
03:55But this is the suggested format.
03:57So I click Save and it creates it with those files for the .h and the .m.
04:03If I look at the interface notice that we don't have the opening and closing
04:08curly brace, we're just saying @interface NSString and then in parentheses our category name.
04:13Well, all I am going to say in here is give it the signature of a method, this
04:18is our interface after all, and my method is going to return, I'll point it to
04:23an NSString, and I will call it convertWhitespace.
04:27Nothing special about this, I just make up my own method name.
04:31Well, of course my implementation does need to fulfill the promises of my
04:36interface, so I jump across to my implementation file, and in here I am going to
04:40provide exactly the same thing and provide the code for it.
04:47Now, obviously here this one really is a very simple example, but whether we had
04:52one line of code or 20, they all work the same way.
04:55So all I am going to do is return a new auto- released object, string my current identity.
05:00I will say self stringByReplacingOccurrencesOfString:@", there we go.
05:09I will say find any spaces and replace with an underscore.
05:15And yes, of course if it was truly a piece of functionality this simple, I
05:18probably wouldn't bother with a category, but you get the idea. I Save that.
05:24I Build it. I am now done.
05:25I have added this new method to the NSString class.
05:29I am going to jump over to my main.m and use it.
05:32Now, bearing in mind that, that new method is not defined in the foundation
05:37Header files, I will need to put an @ sign import just to link to that category file.
05:43That will do the trick, but from that point on I should be able to use it.
05:48In fact, what I will do is here in my NSLog message instead of just using
05:52sentence, which would call the description method, I am actually going to say
05:55sentence and we should have, there we go, a convertWhitespace method.
06:00This object, sentence, is still considered a NSString, we just have a new method
06:06added to that class.
06:08Save it, Run it, and then we should have our string being output with
06:14underscores instead of spaces.
06:16Now, do be aware, this is not just subclassing with another name.
06:20It's not inheritance. It is different.
06:23For example, you cannot add new instance variables using categories, only
06:27methods, but for that feature alone it's great.
Collapse this transcript
Defining protocols
00:01A protocol in Objective-C is a great way to standardize interaction between
00:05objects without worrying about inheritance or any formal relationship and that
00:10sounds all kinds of vague, so let me give you an analogy.
00:14Let's say you want to hire a cleaner for your office, so you might put together
00:18a quick job description on the back of a napkin.
00:21This person must clean floors, must vacuum, must empty trash cans, and
00:24optionally clean windows.
00:25You don't really care who does this or how they do it, you just want someone to do it.
00:31Could be the same person every time, a different person every day. It doesn't matter.
00:35It just matters that someone agrees to do these things and if they agree they
00:39actually do them or at least all the required pieces.
00:42Now in Objective-C this would be a protocol.
00:46A protocol is simply a list of methods you want an object to perform.
00:51It doesn't say how they're done, doesn't say who does them, doesn't matter what class.
00:55It has nothing to do with inheritance.
00:57It's simply a formal list that any class can volunteer to support, and the term
01:01we use is to conform to the protocol.
01:04And if a class says it confirms to the protocol then it better have
01:08implementation of these exact methods, or at least any of them not marked as optional.
01:14However, you won't always be the person writing the list, sometimes you need to
01:19be the person who writes the class that conforms to the protocol.
01:23And in fact, as an Objective-C developer, you'll typically start by conforming
01:26to existing protocols rather than writing one.
01:29And in fact, we've already done that, in an earlier movie we did conform to one.
01:34In the archiving example, we took a custom object, now we were able to have
01:39this object broken apart and saved to a file, and then reconstituted, read from
01:44the file and rebuilt, and we used two built-in classes to do this, the NSKeyedArchiver.
01:49And what that did was take the object and encode it to a file, and the
01:54NSKeyedUnarchiver that read it from the file and decoded it into an object in memory.
02:01And those two objects did pretty much all of the heavy lifting, although we did
02:06have to write two simple methods in our own custom class.
02:10Those methods were called initWithCoder and encodeWithCoder.
02:14And at the time, well, I said was these have to be the names that you use.
02:18Well, the reason those have to be the names that you use is that those are the
02:22two methods listed in a protocol called NSCoding, and that's all that the
02:28NSCoding protocol is, a list of two method names.
02:33And if you go to Xcode Help, and if I were to search on the NSCoding phrase,
02:39I'll find a very formally sounding NSCoding protocol reference.
02:43Well, this has a bit of an overview.
02:46If I come down to it, all it says is that this must provide two methods, one is
02:52called initWithCoder, the other is called encodeWithCoder.
02:55That's all it means to be a protocol.
02:57But what's the benefit?
03:00The benefit is if that we agree to provide those exact methods, we can pass our
03:06custom object into the KeyedArchiver or the NSKeyedUnarchiver.
03:10Because really it doesn't care that we are an employee object.
03:14All it cares about is that we're something that conforms to NSCoding.
03:18That's all it wants to know.
03:20It could be anyone of a thousand different objects, but as long as it conforms
03:24to NSCoding it will have the initWithCoder and the encodeWithCoder methods,
03:29and that's all that these two objects care about, and that's the benefit of protocols.
03:35You can really standardize interaction between objects and there is no
03:38inheritance going on here, there is no formal relationship.
03:42And you'll find as you get more and more into Objective-C programming that there
03:46is quite a lot of protocols that exist.
03:48It will allow you to tap into some great functionality.
03:52So formally how do we deal with them?
03:53Well, to write them, although you may not do this very early on in your
03:58Objective-C career, it is very simple. It's just a list.
04:02In fact, there is a template in Xcode for creating a protocol.
04:05you just list the method names.
04:07No instance variables nothing like that, simply a list of method names
04:12could even just be one.
04:14On the other end is how do you conform to a protocol?
04:18Well, to create a class that conforms to your protocol, you go into your
04:21interface and after the name of your super class, in this case NSObject.
04:27you put the name of the protocol in angle brackets.
04:31Now if you promise that you are going to support or conform to that protocol,
04:35then you better list at least the required methods of that protocol and then
04:40in your implementation simply provide the code for these methods, and they
04:45must match exactly.
04:46And that's pretty much in, now there is not a great deal that you do with
04:50protocols in a command-line tool, in fact, the NSCoding example we've just gone
04:55through would probably be the most common one.
04:57But when you get building iPhone Apps and Desktop apps, you actually run across
05:02more and more of them, because when you're working with those kind of
05:05multi-class, multilevel applications, you'll find that protocols can help with
05:10everything from dealing with spellchecking to handling pop-up alerts.
Collapse this transcript
Dynamic typing
00:01There is a word we've seen a couple of times but haven't yet explored, and that word is ID.
00:06It is a type in Objective-C and it is very common return type in methods in
00:10the Apple frameworks.
00:12Alloc returns an id, init returns an id, and it's common because it's really flexible.
00:18ID can represent any object and it allows us to have both the benefits and the
00:24downsides to something called Dynamic Typing.
00:27So far we've been pretty strict about creating our objects.
00:30We create them with static typing.
00:32We describe that they are NSStrings or NSDates or NSArrays or dictionaries.
00:37Now in this simple project that I have here, I have created three very
00:41straightforward classes called First, Second, and Third, and in fact all of them
00:46are based on NSObject and only one of them has had anything added.
00:50The Second class has one method defined called secondOnly that returns void and
00:55just outputs an NSLog message.
00:58We're going to use these classes just to show some examples of static
01:01versus dynamic typing.
01:02Well, we start off with static typing.
01:04On line 10, 11, and 12, I am creating statically typed objects based on
01:10those three classes.
01:11The good thing about that is it allows me after they've been created to say
01:15use the object called s, which is an instance of Second to call the secondOnly method.
01:23Again, the phrase we use is we're sending it a message here.
01:25If I Build that, it says Build Succeeded.
01:28It's quite happy with it, and I run it, and we get the message coming out
01:31that This only works in the second class, and that makes sense that's what I'd expect.
01:35If however, I change that to represent an instance of the class called First
01:39which doesn't have that method, or when I Build it, it will give me a warning.
01:44First may not respond to secondOnly, but it doesn't stop me running it.
01:48But if I do, here is the problem, Program received signal SIGABRT.
01:53We have a whole problem here.
01:54The actual error message that you're going to get is the unrecognized
01:57selector sent to instance.
02:00Meaning, we sent the message secondOnly to that instance called f and it doesn't
02:05know what to do with it. All right!
02:06Fair enough.
02:07I am going to hit Stop and come out of that.
02:10Just a good example of I shouldn't have ignored that warning.
02:14However, there is another way of defining these objects.
02:19Instead of typing the name of the class, for a second or third NSString,
02:24NSArray, NSDictionary, what I can do is type id. That is a type.
02:31I can then create a variable with a name.
02:34I'll call it whoKnows, because this could represent any object.
02:38Then at some point, could have done on the same line, but I'll do it on a different one.
02:43I can say whoKnows is equal to, and I am going to create an object for it.
02:47In this case, I will create an instance of the Third class just using alloc init.
02:53This is perfectly acceptable way of doing it.
02:56Build has Succeeded.
02:57It has no problems whatsoever doing that.
03:01whoKnows is a dynamically typed variable.
03:05It could represent anything and we're only really going to know for sure at runtime.
03:10What that means is that if I try and use it to call say the secondOnly method,
03:17which we know from looking at it, it shouldn't work.
03:19But if I compile, its not even going to give me a warning about that, because it
03:23has no idea what this object is really going to represent come runtime.
03:26Now that sounds a little vague, because you'd think well, why would I do that here?
03:31Well, the answer is I wouldn't.
03:33But sometimes you don't know this well in advance.
03:38Let me set up a bit more of an explanation there.
03:40I am going to delete that code and I am going to create 100 objects now.
03:49First, I am going to create an NSMutableArray that can hold a lotsOfObjects.
03:54We can just keep adding new objects to this array.
04:04So I am creating a for loop that's just going to go around 100 times.
04:10On the first line of it, I am going to create an integer that's just going to
04:13represent a random number using the arc4random function, which is a part of
04:19the standard C library.
04:21The first part of it's going to give me a number between a 0 and 2, so I am just
04:25going to add 1 to it to make it a little clearer.
04:28Then I define an id called temp, that can hold any object.
04:33And then what I am going to do is check that random number every time I
04:37go around the loop.
04:38If it's 1, I'll create an instance of First, if it's 2, I'll create an instance
04:42of Second, otherwise, I'll create an instance of Third.
04:45I will then take that randomly created object and store it in the array.
04:53Now I have put that temp object in the array.
04:55I don't need it anymore, so I can call release on it.
04:59The array itself will have done the retain.
05:02So that's my duty over.
05:05What I am trying to replicate here is the idea that you don't always know the
05:10objects that you're going to have.
05:11You might be reading in information from an external file or from a web service.
05:16You might be being given a list of bank account or a product information and you
05:20have no idea what these objects are actually going to be.
05:24You just know you're going to end up with a lotOfObjects. So then what?
05:30Well, what I want to do, because that's not really the main part of this example.
05:33What I am really interested in is showing you how we work with them.
05:37How do we work with a bunch of objects when we are not sure exactly what they are?
05:43Well, we'll start off simply.
05:44I am going to do another for loop that's going to go back through
05:48that NSMutableArray.
05:50Now because it is in NSMutableArray, I can use fast enumeration and I can use
05:55the for with an in rather than the int i=0, i<100, and so on.
06:01I could do either way, but this will be easier.
06:03Well, I don't know what each individual objects going to be.
06:07So to loop around them, I am just going to say well, give me back an id.
06:11I will call it eachObject for every iteration, and then say in the name of the
06:17MutableArray, which is lotsOfObjects.
06:21So let's start off simply.
06:22I am going to do NSLog and then say The object is, give it a placeholder, and
06:32then give it the name of the object.
06:34nothing particularly remarkable here.
06:36But bear in mind within this loop, we don't know what that object is.
06:40I can use the generic placeholder Percent sign, At sign.
06:44What that's going to do is called the description method on every object.
06:48Every object will have one because it's a method that exists in NSObject.
06:52So we'll run it and see what happens.
06:54Run and we do appear to be having kind of a random selection of
06:58different objects here.
07:00The default description method is actually writing out the name of the class and
07:04then the address in memory.
07:06Now why I quite like looking at this default output is it's obvious that even
07:11though we're just splitting out an id, the object itself knows what it is,
07:17and that can be useful.
07:18Now taking this a little bit further, I am going to leave that as is.
07:24Jump over into one of my classes here, let's say on the Third class, and jump
07:31into the implementation, and I'll quickly just override the description method
07:42returning a custom string here.
07:44The reason that I am doing this is just jumping back into main.m. We'll run this again.
07:49The more we can see is that when the object is of type Second or First, it's
07:56using the default description method.
07:58When it's of type Third, it's actually using the overridden one in the Third class.
08:04While the actual output of any of these isn't very exciting?
08:07The point is what we're doing here is what's called the Polymorphic Method Call.
08:12Even though within the body of that loop, the type of these objects are id, it's
08:17calling the right thing at the right time.
08:20Let's take it a step further.
08:23What happens if for example, I say each object secondOnly?
08:28Well, it will let me write this code.
08:31It will even succeed with no issues whatsoever.
08:34But again, what's going to happen is I will be sending the secondOnly message
08:39to the wrong kind of class and very quickly we're going to get another
08:43exception, no surprises there.
08:45But what I might often want to do is say well, I know I could have 100 objects
08:50here, but sometimes they will be of that Second class.
08:53So surely, it should work in those cases.
08:55Well, we can check it.
08:57What I can do here is put in an if statement.
09:00See every object will have a method called isKindOfClass.
09:05What we can do there is put in the name of the class space the word class.
09:13They all have this method too. Close this off.
09:16That returns a Boolean value.
09:19I don't explicitly actually need the opening and closing curly braces for one
09:23line, but I prefer to have it.
09:24So I am asking if with every iteration of the loop, this particular object is of
09:30the type Second, then I can call that method, so let's run that.
09:33Now what we can see as we're going through this is that I am getting different
09:39ones being written out, but if the object is of the type Second, I am then going
09:45on to call that method.
09:49Alternatively, rather than asking whether the object is a particular kind of
09:55class, another if statement that I can ask for will be if eachObject
10:01respondsToSelector and that will be very useful in the case that I might have
10:06multiple objects with the same named method.
10:10Selector again is the equivalent of our method name.
10:14Basically saying if we send this particular message to the object, will
10:19it respond, yes or no?
10:21The way that we do this is actually by using the word At sign selector and then
10:26just giving it the name of the method.
10:30Use the Square Bracket just to finish that off and calling it again.
10:40So what we should be able to do is have two occurrences of that method.
10:44Call one right after the other as long as the class is of type Second.
10:50Save that, run it, and yes it does appear to be the case when we're getting
10:54the one message output.
10:55We're getting it both responding to the isKindOfClass and responding to
11:00the respondsToSelector.
11:01Now as you can imagine, dynamic typing is kind of a difficult thing to explain
11:08in a short and somewhat contrived scenario like this.
11:12The point is you don't always know what these objects are in advance.
11:15Now I am a fan of statically typing as much as possible, because that does put
11:20as much as checking as I can to the compile time.
11:23But Objective-C as you can see is perfectly capable of determining the identity
11:28of objects at runtime and you will need to do this from time to time.
Collapse this transcript
11. Debugging
Common compile errors
00:00We write a bunch of code, we hit Command+B and we get build failed along with a whole bunch of
00:06cryptic error messages.
00:09When this happens to you don't start cherry picking the ones you think that you recognize.
00:14The rule is start at the top and work your way down, because the first
00:18mistake can have a domino effect and cause multiple issues down the line that aren't problems.
00:23In fact the main problems might not even be in the file that you are
00:26currently looking at.
00:27So do make sure that you have your issue navigator opened that's the middle
00:31button in the navigator, the one that looks like an exclamation mark.
00:34If you have multiple files, pick the first file, pick the first issue and fix that one.
00:40In this case, it says missing terminating double quote character.
00:44Now that's fairly straightforward, so in line 3 yes indeed I do have that, hit
00:49the double quote, and hit Save, hit Build again.
00:51Now we have just fixed every single problem, well I wish I could say it was
00:54always going to be that easy.
00:56you are going to run into a few more errors and warnings than that one.
00:59So let me take you through a few of the most common ones.
01:02I am going to jump over to a project here, where I have written a whole bunch of bad code.
01:08These first ones are going to cause errors, the red stop sign, the
01:12exclamation mark of doom here.
01:14Again if you get that error and you are perhaps on a different area, what you
01:18want to do is click that issues navigator and it's telling me that I have one
01:23error which is the semantic issue that the interface type can not be
01:26statistically allocated.
01:28Well this is X-code's friendly way of telling you forgot the pointer.
01:32That is what this error means that you tried to create an object and all objects
01:37are pointed types, but there was no asterisk but simply by adding the asterisk
01:41we get build succeeded.
01:43Moving on to error number two, also very common, save and build something and
01:48you get a few messages popping up.
01:50I have got three over here in my issue navigator and one that I can see here,
01:54expected semi-colon after expression.
01:57That one is pretty straightforward.
01:58I can look at that statement on line 17, yeah, forgot to terminate and
02:02didn't add semi-colon.
02:04To bear in mind sometimes we will get the fix it, the suggestions, they can pop
02:08up if you click on the gutter, although I find a more reliable way is to click
02:13the actual issue in the issue navigator and we will get to fix it down here, to
02:17suggest to insert a semi-colon.
02:18Yes, looks good, I hit Save, and I hit Command+B to build again, build is still failing.
02:24Now what we are getting here, is a parsing issue.
02:27expected closing curly brace.
02:29Now you can see a lot of messages that include that word expected and they all
02:34tend to mean that you missed a curly brace or a square bracket or parenthesis.
02:36When I click it it's taking me down to the bottom of the file, saying it's
02:41expecting a closing curly brace.
02:43Now it wouldn't be a good idea for me to add it, I know I didn't change the code
02:47down here, but it's because I braces can last for quite a while, the issue is
02:52really back up here.
02:54On line 15 I am opening a curly brace, then I am immediately opening one
02:58again and I am only closing it once, so something is not pairing up and that's the one.
03:03I will hit that save it, there we go build succeeded.
03:06moving on to the next one, a very common error, use of undeclared identifier.
03:11Now this is actually four errors in two lines, which is pretty impressive.
03:17As you will see there is actually nothing wrong with these lines of code, almost
03:20we are most interested in the one at the very top, we can ignore the rest.
03:26So selecting in the issues navigator says it's an undeclared
03:29identifier, myNewClass.
03:31Well let's say that I had just written this and I know I did, if I click over
03:35here, just to verify, in my code I have got something called myNewClass, yes I
03:39am using the right spelling and the right case sensitivity.
03:42It looks fine, there is my implementation.
03:44So what's the problem?
03:46Well undeclared identifier always means I don't know what this is, and reason
03:51for the problem is I am not importing a header file.
03:53Now it's a very common reason for use of undeclared identifier whether it's your
03:59classes or something else.
04:01that's a very common reason for undeclared identifier.
04:04Whether you are trying to create a new class that you wrote or trying to link to
04:08say something else in one of the Apple frameworks.
04:10So I import the header file, Save and Build and again my build succeeds without
04:14me having to change either of those two lines of code and just as an addition to
04:20that one, we have got the use of undeclared identifier and a string and just as
04:26it related addition to their error, if you get the same message the undeclared
04:29identifier on an object that you think exists well again it's probably down to
04:33the whole case sensitivity thing.
04:35Objective-C is of course very concerned about knowing what everything is and in
04:39fact error four, which technically isn't an error.
04:42It's a warning it's related to those two as well.
04:44Now what I am getting here it the implicit declaration of function NSLog is
04:49invalid in C99, a very long winded phrase to say I don't know what NSLog is.
04:54now looking at that what I can see is, it's meant to have an uppercase L, and
05:01that should do the trick.
05:03Error number five, still something that I run into or I see people run into
05:07from time to time, particularly based on the language background build failed
05:12here, unexpected @ sign in program and whenever I see this, I think some one
05:17coming from a language where it doesn't matter if you use double quotes or single quotes.
05:20Well it matters here, the only thing that uses single quotes are chars,
05:24NSStrings which is what we are doing here, need to have double quotes.
05:30Next up, let's talk about some common warnings.
Collapse this transcript
Common compile warnings
00:01So let's talk about some common warnings that you'll run into when building your projects.
00:06Now there is one warning in Objective-C that I absolutely hate.
00:09I consider this one to be a vile deceptive gateway drug of a message that snares
00:14new developers into its evil web, and it's this one.
00:18the unused variable warning.
00:21Now you might think, okay, Simon has finally lost it.
00:24Why would he hate this message?
00:25I mean finally we have a message that a, isn't cryptic.
00:29It's very straightforward.
00:31It's telling us you declared a variable, and as far as it can tell you don't use
00:34it, and b, that's true.
00:36That's no big deal, no real problem with the unused integer, unused float,
00:42even an unused string, and that's precisely why I don't like it because it's easy to ignore.
00:48This unused variable warning is the most common warning you're going to get in
00:52development and it can lead people to have a blind spot with these little yellow triangles.
00:57But the thing is most warnings are not like this, most warnings are significant
01:02logic errors that will make your program crash.
01:05They'll make it give wrong data, they'll make it leak memory.
01:08You should never ignore a warning.
01:11One of the issues too is depending on your settings, it won't always throw open
01:14the Issues Navigator.
01:16So you should keep an eye on the little iTunes style display up at the top
01:20here to see if there is any little yellow triangles and again use the Issues Navigator too.
01:26So I don't even like to keep these ones hanging around, so I will comment them
01:29out just so it doesn't keep complaining about them.
01:32Let's go through a few of the other more significant warnings.
01:36Here's a pretty common one and the warning is incompatible pointer types
01:42something, something, something.
01:44I am showing two different versions of this because you'll find them
01:47phrased different ways.
01:48While most say incompatible pointer types something, something NSString,
01:52something, something char array, and the other one will do the opposite and
01:56incompatible pointer type something char array, something, something, NSString.
02:00Both are the same problem.
02:02We've missed the @ sign in front of the NSString object.
02:07So here for example we are making an NSString object, we need an @ sign in front
02:11of the double quotes as we do in the NSLog message.
02:14This is something that all developers new to Objective-C are going to hit once in a while.
02:19So many languages just use the double quotes that it's easy to get into the
02:22habit of doing that.
02:23So just keep an eye out for it until you're used to that whole
02:27NSString double-quote thing.
02:29Moving on, another very common warning.
02:34The message here is, Using the result of an assignment as a condition without
02:38parentheses which is Xcode's way of telling you you're using a single equals
02:43sign in an if statement, shouldn't that be a double equals sign?
02:46If I am asking if C=D, it needs to be double equals, otherwise this is
02:51assignment I would be setting C=D, and the if statement would always be true.
02:58This is one of these warnings that will typically give you a fixit if you
03:01highlight the issue in the Navigator here.
03:05It will throw up the little fixit here, Use '==' to turn this assignment into an
03:08equality comparison, but be careful because there is another option here in the
03:12fixit, which is, Place parentheses around the assignment to silence this warning
03:16which is certainly not what I want.
03:18I want to use the double equals sign and there we go.
03:21Moving on, warning number four, a very common one but a really significant
03:26one if you let it go.
03:27Now this warning I actually need to make a little tweak in a separate class file here.
03:32What this warning is all about is the idea of having a method that has
03:37been defined here on line 6 to return an NSString that somehow doesn't return something.
03:43Now, this is very, very common too.
03:45Again, if I am back in Main, I am saving, I am building.
03:48Build has succeeded, the only indicator that there is a problem is up here.
03:54I've got the little yellow triangle.
03:56Again, jumping across to the Issue Navigator and the issue here is Control may
04:02reach end of non-void function telling you, hey!
04:06This method is defined to return an NSString and I've detected that there is
04:10a way that you may not get that NSString back, and in this case whether it's
04:15intentional or not.
04:17That's because I've got a little if statement on line 10.
04:19There is no curly braces after it, which means, that's the same as having
04:24this enclosed in braces.
04:26So there is a possibility that it's detecting that I might not always hit
04:31a return statement.
04:32Yes, I might get it, I might not.
04:34I really want to make sure that whatever happens whether I use an else
04:38statement or whatever that I do have some kind of return statement that sends back an NSString.
04:45Obviously it's the same if it's an int, if it's a float, anything.
04:48You always need to be able to return something because even if you don't think
04:53that's important, back in Main.
04:56bear in mind what's happening as I am calling that method, I am expecting a
05:01result back out of it.
05:02I am going to do something with that result, so it could have significant knock
05:06on effects, and that was the Control reaches end of non-void function.
05:12And the last one that I am going to point out here, again a very common one, I
05:15am going to save it, I am going to build it.
05:18The warning is, NSString may not respond to groovyMethod.
05:22Now, the bit that should be jumping out of you is not the front and the end of
05:26this, it's the middle bar, may not respond to.
05:30This is Xcode telling you, hey!
05:32I don't think this object does what you think it does, and the reason you'll
05:37often get this is calling the method on the wrong object.
05:42Let's say I was copying and pasting some code.
05:44I wanted on line 34 to create a new instance of my new class and then I was
05:49going to call the groovyMethod on it, but maybe I copied and pasted from another
05:54few lines and I am accidentally using the wrong object, I am using an object of
05:59NSString rather than object of my new class.
06:03Objective-C won't make this an error because of things like dynamic typing.
06:07All it's ever going to do is make its best guess at what objects respond to what messages.
06:12So it's just telling you.
06:14may not respond here.
06:15Again, the issue with this kind of warning is it won't stop you.
06:20It will allow you to build, Build will succeed, problem is when I hit this line. Well, let's do it.
06:27Let's run this application.
06:28What it's immediately going to do is basically crash.
06:33We're in debug mode, so we could go through and start seeing things but
06:36terminating the application due to the uncaught exception, unrecognized
06:41selector, all going back to that idea.
06:44I don't think that this object does what you think it does.
06:47Now because I don't like the idea of warnings like this allowing me to just
06:54plough on and run the application, what I often do with my projects on a
06:58project-by-project basis is I change the settings so that warnings are treated
07:03as errors and they won't actually let me run the program till I fix those.
07:08The way that you do this is by jumping to your Project Navigator and just
07:12selecting the very top icon that represents the project itself.
07:16This is where you find an enormous amount of different settings and things you
07:20can change, most of which you'll never have to touch, but if, and the way that I
07:26typically go about this is I select the PROJECT, I go to Build Settings, make
07:30sure I am looking at all the options, and then just about right down the bottom
07:35here, one of the options that I have is this guy, Treat Warnings as Errors.
07:42What I can do is change that to Yes.
07:45This is not a general Xcode setting. It's per project.
07:48But what this will do is when I now try and build, the Build will fail.
07:54It will not let me go on and run this application until I fix this problem and
07:59suddenly realize, oh!
08:01That's right, I don't want to call it on result, I wanted to call it on that my
08:05third object that I just created on the previous line.
08:07We build that, Build succeeded, now we can go ahead and run it.
08:11I scan up at the top, no warnings.
08:13Now, having a successfully built project doesn't mean that it won't crash the
08:18moment you run it but we can deal with those issues, the runtime issues next.
Collapse this transcript
Common run-time errors
00:00This is programming.
00:02There are a million ways your program can go wrong once it starts to run, but
00:06there are a few common ways that things do go wrong in Objective-C and just as
00:10importantly a few ways that they don't. You see Objective-C is a very forgiving
00:15language, and because of dynamic typing, if you do something that doesn't make
00:19sense, it may just ignore you instead of crashing.
00:22So let me give you an example.
00:29I am going to create a pointer to an NSString object here.
00:33I'm going to forget to instantiate it.
00:35It doesn't created, and then on line 9, I am going to send it a message to the
00:40method uppercase string, and on line 10 I am going to send another message,
00:43telling it to write to file.
00:45I am passing it a whole bunch of parameters, but I am never creating the object.
00:49There is no alloc init, and there is no shortcut convenience constructor.
00:55So let's run this and see what happens.
00:58Well it builds, Build succeeds and it spits out a message here saying, got to
01:02the end of the program, which is just a simple NSLog I have right at the end.
01:06Now if you're coming from C# or Java, you are likely to find this fairly
01:11surprising, because this wouldn't be allowed in those languages.
01:14You try and call a method on a null object and you are likely to crash.
01:18But in Objective-C, you can send messages to a nil pointer, which is what we have here.
01:24See the variable called emptyPointer does not point to an area of memory yet, no
01:29object was ever instantiated.
01:31It was never given an address.
01:33Those messages will just be ignored.
01:36However, that doesn't mean you can just send any message to any object.
01:40That won't work and it's one easy way to go wrong.
01:43Let's say I create a new NSDate object, and then I decide to send it the message
01:52uppercase string which is a method that exists in NSString not in NSDate.
01:58Now the compiler is giving me a warning here, and the warning is actually
02:02saying that NSDate may not respond to uppercase string, but I could still go ahead and run it.
02:07We are going to get instantly this Program received signal:
02:11"SIGABRT", and if I look down here in the output, it's terminating application
02:17due to uncaught exception.
02:19The important thing here is this one.
02:21unrecognized selector sent to Instance.
02:24Now you might say, well that's okay, we got the warning, if we weren't ignoring
02:27the warning, there wouldn't be a problem here, but not necessarily.
02:31For example, I could have defined this as an ID and if you remember that, an ID
02:36can represent any object.
02:38In this case, I wouldn't have got any warnings whatsoever, because of the
02:42dynamic typing or maybe this object was an NSDate maybe later on it will be something else.
02:48But of course when we run it, we will still get exactly the same problem we are
02:52instantly going to crash.
02:54So just because you can send messages to an object that's never been
02:58instantiated, and you can send it anything, that's quite a different matter
03:02after that object has been instantiated, and it really does represent something.
03:06Now the classic other way to go wrong, and I am going to comment out this code
03:12here, is that we create a new object, I'll just make an NSString.
03:19Next, I release it.
03:25Then on line 19, I am going to try and create a new string based on that old one.
03:30I am going to call the method uppercaseString send in that message and then on
03:34line 20 send it out, let's run this one.
03:38The Build has succeeded, and we are starting to run, but here is the problem,
03:42and you might have to scroll down if you don't immediately see it.
03:45Program received signal: "EXC_BAD_ACCESS".
03:51Now there are occasionally circumstances where in a super, simple program like
03:56this you might have it work, even though it's been released, because there just
04:00hasn't been time for the runtime to actually clear that object out of memory.
04:06But of course, what's happening here is that we've created this object, we then
04:10release it, then we try to use it, and the EXC_BAD_ACCESS is the classic example
04:17of trying to use an object that's been released.
04:20Now the thing that often confuses people when they are new to this is, what's
04:24the difference between this nil pointer up here like emptyPointer that
04:28doesn't point to anything?
04:30And this will release down here which has been released.
04:34What's the difference between the two?
04:35Well, on line 17, we are releasing the object, but the pointer still has
04:42the address in memory.
04:44It is not a nil pointer.
04:46It's pointing to a space that's been reclaimed.
04:50If I wanted to be doubly sure that this program would work, what I could do is
04:54set willRelease = nil.
04:59This doesn't do anything in terms of releasing memory.
05:03That's all being taken care of by the runtime.
05:06It's all being taken care of by reference counting.
05:09What it does is blank out the pointer, and then if we try to use it on line 20,
05:15well it's actually going to run.
05:16It's going to run all the way through.
05:18The new string that I try and write out from line 21 is going to be null,
05:23because nothing was ever there, but we are going to actually continue.
05:26So you will see that Objective-C is very forgiving in some circumstances, and
05:31very unforgiving in others.
05:34But these are perhaps the classic two runtime errors when it comes to
05:37working with objects.
05:39either trying to send messages to objects that don't support them, or trying to
05:43use objects that have been reclaimed.
Collapse this transcript
Exception handling with try/catch
00:01If you've used structured exception handling in other languages, you will
00:04be glad to know that it exists in Objective-C as well, and if you haven't,
00:08well you're about to.
00:09The idea here is pretty straightforward.
00:11Sometimes we have code in our programs that we know might cause an error.
00:16And if we can't do anything above that it's going to cause our program to crash.
00:20I have two lines that actually will cause an error here.
00:22On line 9, I'm creating a new object of type NSDate and on line 10.
00:28I'm sending it the message to uppercaseString, and unfortunately uppercaseString
00:32is a method that's defined in NSString not in NSDate.
00:35Now the compiler isn't going to catch this because I've typed it as type ID,
00:40which could be appointed to any object.
00:42But if we run this we're going to have a problem. Pretty much immediately this
00:47one's going to crash with this board unrecognized selectors send to instance,
00:52and the program is terminated. So what can we do?
00:55Well we're using what's called Structured Exception Handling.
00:59It's a piece of code that's made up of three points, Try, Catch, and Finally,
01:04and in fact the easiest way to get use to it is to just grab it from the Code Snippets Library.
01:09If I open up my right-hand side my Utilities panel, make sure I'm on Code
01:13Snippets Library with the braces, and then it's in there somewhere I might as
01:16well just search for it, type in the word Try, and here I've got two, the
01:21C++Try/Catch Block, certainly not what I want, and the Objective-C Try/Catch
01:25Block that looks good.
01:26Let me make sure that I've stopped this application and there we go and I'll drag it over.
01:32So three parts to it, all beginning with the beginning with the @try, @catch,
01:36@finally, each having their own statement block with the curly braces.
01:40The Try is the code that we're worried about.
01:43The code that might cause an exception.
01:46might cause this error to happen, so what I'm going to do is take the code I'm
01:50worried about, cut it from up there, and then just paste it in down.
01:55It's getting a little ugly formatting wise, but I'll tidy up in just a moment.
01:59The next block is the Catch block.
02:01What happens is, whatever code is in Try, whether it's two lines or 20 lines,
02:06we're going to go through line by line, and if anything causes that error, we're
02:10going to jump into the Catch block, we're going to wrap that error up and pass
02:14it in as an object called an NSException, and here it says.
02:18well, this is going to be passed in as a parameter here.
02:21So what do you want to do to do with it?
02:22Well, here I might output a message, I might log something, I might save a
02:27problem to a file, I might pop up a message box if this was on a Desktop or an
02:32iPhone, but here all I'm actually going to do, to prove the point is we're going
02:36to log out a message.
02:38There was an error, and because I'm being passed an object that's going to be
02:44called Exception, I might as well write it out and see what it's made of.
02:48It is an object, so I'll do the percent sign, at sign, and say Exception.
02:54There is nothing magical about that name, if I wanted to change it to just e
02:58here, I could change it to e here.
03:00It's just what is this going to be called, but Exception is good.
03:03And then we hit the Finally block, whatever code I put in the Finally block will
03:09be executed regardless if everything in the Try block work correctly or if the
03:14first line or third line, or seventh line and Try through this exception and we
03:18had to jump to the Catch block.
03:20Now I don't actually need to put anything here, I'll just put this message out.
03:27The reason that the Finally block exist, is let's say what I put in the Try was
03:32saving information to a database.
03:34It might work, it might not, but regardless what I want to make sure that I do
03:39is in the Finally block I'm going to close my connections to my database.
03:42So there is nothing particularly important here, I'm going to garb this code and
03:46just hit Ctrl+I to format it a little bit better, and then let's run it.
03:51So I'm just going to shrink this down to show just the Target Output, make it a
03:54bit more obvious here.
03:55So what we're getting is the message unrecognized selector, and you can see
04:00where I'm writing out myself whether there was an error, but see that I'm also
04:04jumping to that Finally block.
04:06It is not causing the program to crash, in fact, if I look at the logs here,
04:12I've got the fact that this one ran, there was a Debug and there were no issues,
04:15we ran it, not a problem.
04:17As far as this is concerned, we finished successfully.
04:22We can run it again, we can run it again, and we can run it again.
04:25Of course, what you want to be doing with your code is writing in such a fashion
04:32that this doesn't happen anyway, that as much as possible, exemptions never
04:37occur, that you're always checking beforehand, so that you don't have to worry
04:41about Try and Catches and Finals.
04:43But in those rare circumstances where you're aware that a combination of
04:47conditions might make things a little bit tentative, this is a great asset to have.
Collapse this transcript
Breakpoints and debugging
00:00When it comes to really understanding what is going on in your code there is no
00:03substitute for a proper debugging session on using and using X-code we can step
00:08through our code line by line as its executing.
00:11The simplest way to do that is to pick a line that we want to stop on.
00:15I am going to pick line 15.
00:17there is an NSLog message here.
00:19What I am going to do is come over into the gutter and just single click here.
00:23This creates the breakpoint.
00:25That's what this blue icon represents, saying that when this program runs,
00:31stop here and allow me to browse through the code and continue to execute line by line.
00:36Now the shape of the breakpoint matches a shape up here on the navigator and if
00:40I in fact click that it will keep a list of any breakpoints that I click on in
00:45the gutter or turn off.
00:46Now you notice that if I single click and then single click off again, what
00:51happens as the breakpoint doesn't go away it becomes deactivated.
00:55Now that I can be useful but maybe I just created it by accident.
00:59Well to delete a breakpoint I can actually deleted from the navigator or I can
01:05drag and drop it off the gutter and it disappears in a puff of smoke here.
01:09But let's say what does.
01:11So with this breakpoint activated I'm going to click the Run button, build succeeded.
01:16It runs it executes the first few lines of main.
01:19it hits that breakpoint and stops.
01:21We are now in a running program.
01:24It's waiting for input.
01:25Now what you can see is up here on line 910 I have created some variables and
01:29done a little bit of interaction with them and then down here on the left-hand
01:33side of the debug area we have the variable section and this is actually showing
01:38me the local variables that are currently in scope A=300 I could actually double
01:44click that and change that value if I wanted.
01:46I can see the variable B, I can see there is a string called simpleString
01:50here that must have been initialized and yes indeed it was on line 14 with a value test string.
01:57You not only have this list down here in the variable section but you can mouse
02:02over a variable itself to see what's inside it.
02:05mousing over here integers I can also mouse over a string or even
02:09an NSAutoReleasePool.
02:10Now that there is an awful lot of data, some of them you can expand by clicking
02:16the disclosure triangle, to see some of the internationals of what's going on.
02:20So with the little green indicator here our question is now what do we want to do?
02:25We stopped before the line NSLog.
02:28So this line has not actually executed right now and I want to execute it and move on.
02:32Well I have a couple of choices and everything is driven from these buttons down
02:36here at the top of the debug area.
02:39This first one looks like a Play button on a VCR.
02:43Continue program execution, just keep going either till the end of the program
02:46or till you hit next breakpoint.
02:48This one is called a step over and the next one is called step into and we will
02:53see what those do right now.
02:55What I'm going to do here is click this button it executes the line in the NSLog
03:01and I actually can see you can see over here in the output its output of the
03:04string is a test string.
03:06Now were paused right before the call to simple function.
03:10Now if I click this button, the third one this is the step into button which
03:14means execute this but as it's a function called we're going to jump into the
03:19function which is actually down at the lower part of the screen.
03:23Now if you notice that the local variables change because we're in a
03:26different scope it might have some odd values depending on whether they have
03:30been initialized or not.
03:31I'm going to keep stepping into a setting those values and I can see them change
03:37in the variable screen below.
03:39We hit the NSLog message, I come to the end of the function and what's going to
03:44happen when I'd step into it again we are just going to continue executing
03:47jumping back into the main function, we are finished what our call to simple
03:51function we're on to the next NSLog.
03:54We output a message.
03:55we are creating a custom class.
03:56Now these next lines 20 21 and 22 these are using a class that I've created
04:02myself a custom class because I have the code in my project what that means is
04:09it's going to jump into the init method here.
04:13So if I hit this step into I'm jumping actually into a completely different
04:18file into a simple class.m where I have got a custom init method I can start to
04:23jump into that and keep going return we jump back in and back in main now it's
04:30call to simple method we jump over we output another message I keep on stepping through.
04:37Now let's say for example that I realized that we're jumping into a lot of code.
04:41I am having to step through quite a few things.
04:43One of my other choices because I can see there is another call coming up to
04:46simple function or maybe I don't want to jump into it, I do want to execute it.
04:50So what I will do instead is I will click this option which is a step over.
04:55Now step over doesn't mean bypass.
04:57It means execute this function but I don't need to go into and see every single line.
05:03Just executed and move on.
05:05So if I click that we move on to the next line, we did execute that function and
05:10it wrote out the message in the simple function writing out 199.
05:14I can come down a little bit here, give myself some room and now I am
05:18jumping into a loop here.
05:20It begins initializing on line 29 we're creating a new instance of my custom
05:25class that means when I hit that line we are going to jump into the init.
05:29Again I might be thinking I didn't want to do this but what I am going to do is
05:34continue executing this init method, but just say I want to continue on and then jump out.
05:40that doesn't change anything about how the program executes it just allows me to
05:44skip past a few lines and come back to where I was before I called it.i now jump
05:50on and we keep going.
05:52Now I could make this a little quicker by using the step over which means I can
05:57at least start to rotate around that loop but it would certainly get a little
06:01tedious to have to do this a hundred times particularly as I can see that the
06:09integer counter is only equaled 11 right.
06:11So what would be a good idea well what I am going to do is come down and click
06:15in the gutter and create a breakpoint just before this NSLog message come down
06:20to the bar here and just click the Play button, keep going bang!
06:25We've gone through that loop a hundred times.
06:28In fact if I look at my variables here, it's a little difficult to see it's gray
06:31there but there are hundred objects in it now.
06:33We are now out of the loop I could choose either the step into or the step over,
06:38they both work the same way here.
06:41We drain I click Play and we finish.
06:45Technically X-code is using the GNU debugger GDB in the background.
06:50So if you are familiar with that you can even start typing in, in the debug area
06:54over here if you wanted to.
06:58But as you can see a very simple way to start jumping through your code.
07:02very easy to start creating and manipulating breakpoints choosing to jump in or
07:06jump out of different pieces, choosing when to stop one to look at things.
07:11You can also set watches and expressions, I am not going to get into this
07:14in this particular movie but do have an experiment with that and see what you think.
Collapse this transcript
Upgrading code to utilize ARC
00:00If you have Xcode projects created prior to ARC, including many of the
00:04exercise projects for this course, they will continue to work correctly. You can open them
00:09up in Xcode, and they'll work just fine. Xcode will not force you to migrate anything to
00:14ARC, but it might be a good idea to.
00:16So I'm opening an older project here that was created prior to ARC's existence.
00:22It's from the Archiving Chapter earlier in the course. Even from just taking a quick look at that
00:27I can see there are some things that need changing. We're working with the NSAutoreleasePool
00:31Object, that shouldn't be used with ARC, we have got calls to release, pool drain, and so on.
00:37If I looked further into the actual objects here, I have got the dealloc method with a call
00:44to super dealloc. I know that kind of thing is not allowed in ARC. But even so, I can
00:49actually go ahead and build this. It should build successfully, because we don't have
00:54to use ARC, so projects opened beforehand will work just fine, and when I open an older
00:59project, it's worthwhile looking on the Toolbar here. I can see that I have got one warning popping up here.
01:04That right now says validate project settings, and we should work with these first.
01:10So if you are getting any complaints, deal with those first. It's suggesting that I upgrade
01:14the debugger from GDB--the older one--to LLBD. That's fine. I am going to go ahead and perform those changes.
01:19It's asking if I want to take snapshots before cleaning up this project,
01:24for my purposes, no, I don't.
01:26So I have dealt with that. We have no issues. I have done nothing yet about converting to ARC.
01:30Now we have seen earlier that ARC is something the compiler does. So one question might
01:35be, how do I know? How do I know if ARC is on or off for a particular project?
01:40Oh, one clue might be just looking at your code and seeing if you have things like NSAutoreleasePool
01:45being used, that's not ARC compatible. So this is telling me that this project isn't ARC.
01:51But what if I want to formally look, what I need to do is look at the Project Settings
01:55for this project. How I do that is by clicking the very top icon in the Project navigator
02:01here, the one with the project name. In this case, Archiving. So selecting that icon, we have
02:06settings that we can read over here. We have got settings for both the project and want
02:10called the target. If I select the Project Settings we find a section called Build Settings.
02:15Now there's an awful lot of stuff that goes on here, most of which you'll never need to touch.
02:22But the setting or whether Automatic Reference Counting is turned off or on is actually buried in here.
02:26The easy way to find it is using this box, I can search on Automatic, there we go.
02:33As I'm starting to type it, I'll see there is an Option under the Apple LLVM compiler,
02:38what Xcode is using behind-the-scenes to compile our project, and it says Objective-C Automatic Reference Counting: No.
02:46Now you might be tempted to just change this to Yes. That would be the wrong way to go about
02:49it, because it'd be incompatible. Xcode can help us migrate this project to Automatic
02:55Reference Counting. I don't want to just flick this option to Yes, because there's all sorts
03:00of things going on that are incompatible with ARC. So to probably convert a project to ARC,
03:05I'm going to go to the menu Option under Edit in Xcode, come down to the Refactor section,
03:11where I'll find Convert to Objective-C ARC, click that, it's going to ask what Target
03:17you want to Convert. I only have one here, a typical project with a single target, meaning
03:21what we will actually compile this into, it's just one program.
03:26I'll click check, it'll step us through a couple of different screens about converting
03:30to Automatic Reference Counting, click Next on this panel, and what it's going to do is
03:36now give us a Preview, give us a comparison of the things that it's changed between our
03:42project as it was before, and what it's doing afterwards. What we're actually seeing is
03:46the before is on the right-hand side and the after is on the left-hand side.
03:52So by scanning it I can see that in the Employee Header file it's changing the retain property
03:58to a strong property. If I jump into the implementation file, I can see that there are a couple of
04:05calls to retain that are being removed, because those aren't necessary anymore, ARC will take
04:09care of figuring out when an object needs to be retained. Not only that, but I can see
04:14the dealloc method in the original one has been completely removed in the converted one,
04:20because it's just not needed anymore.
04:22If I jump into main.m and take a look at the changes there, I can see that the NSAutoreleasePool
04:27on line 6 has been changed to an at sign, @autoreleasepool block. If I come down a little
04:32further to see what else is going on, we have got a call to release, doesn't need to be
04:35done anymore, and the drain of the pool has been replaced just with the closing brace
04:40of the at sign @auto release. That all looks good, I'll click Save.
04:46I jump over into my main, where I can see that I have got some simpler code going on now,
04:51but if I go ahead and click Build, Build Succeeded. We have now successfully converted this project into ARC.
04:57Now for additional information, take a look at the developer.apple.com web site,
05:05and what you'll find is in the Mac OS X Developer Library, there is a document on transitioning to ARC.
05:11Sometimes it's a little difficult to find, but you'll find it in the Release
05:15Notes Section, or you can search for it. Transitioning to ARC Release Notes will actually go into
05:20Detail about some of the things you should be aware of when converting older more legacy
05:25style projects with a lot of code.
05:27So this contains more information on the Technical Details if you need it on the common issue
05:32when migrating projects. Most of these things we have actually talked about, there are a
05:35few more unusual things that ARC will choke on. Like if you have defined your own Custom
05:40retain and release methods, these aren't allowed.
05:43So there are suggestions in that document for you might do instead, and it's certainly a
05:47worthwhile document to have on hand the first couple of times you migrate a larger project to ARC.
Collapse this transcript
Conclusion
Exploring and using other frameworks
00:00From this point on, most of what you'll do is less to do with the language
00:03itself, and more about the frameworks that you will choose to link to and use.
00:08Of course, in this course we have concentrated on the language by creating
00:11simple Command Line tools that use the Foundation framework.
00:15little over hundred classes that we can use in any code we write.
00:18If you move into building Desktop apps, you will be using Cocoa, and if you're
00:22building iPhone or iPad it's often referred to as Cocoa Touch.
00:25Now these things sound like there must be some massive pieces of software
00:29architecture, but they're really not. In fact they are quite deceptive.
00:33Cocoa itself is kind of a hand-wavy vague term that's often used just I mean
00:38general all aspects of Apple development.
00:42And there is a good reason for this, let's go and take a look at what Cocoa actually is?
00:47So I find them in Xcode and I create a Cocoa application instead of a Command Line tool.
00:51I'll give it a name. Let's just call this FirstCocoaApp.
00:54Now it does want me to give a Company Identifier, which is often your Company in reverse DNS.
01:00So I am just saying com.lynda here.
01:02I'll leave all the rest blank and click Next.
01:05It will go and create this application for me, and instead of linking to the
01:10Foundation framework, we are now linking to the Cocoa.framework which sounds
01:14very impressive, and isn't.We know that we could break the Foundation framework
01:19into loads of different header files.
01:22Well if I expand the Cocoa. framework, I see precisely one.
01:26You see Cocoa itself contains nothing.
01:30There are no classes, there's no functionality, there's no code at all.
01:34All Cocoa technically means is linked to these three other frameworks.
01:41Foundation, AppKit and CoreData.
01:44Foundation is the one we have been using all along.
01:47AppKit contains classes for developing desktop apps.
01:50They represent Windows, menus, buttons, fonts, images though it's not just
01:54visual, there are also classes in AppKit for background functionality,
01:58spellcheckers, event handling and the application itself, and then CoreData.
02:03This is a framework to help you persist your objects to save them into storage
02:08and read them back from storage.
02:09It's recently become the recommended way to store your data, but technically you
02:13don't even need this for Cocoa, because while this is the technical meaning of
02:18the Cocoa header file, in general discussion with other Apple developers, Cocoa
02:22really just means Foundation and AppKit on the desktop or Foundation and UIKit.
02:28which is the iPhone equivalent and iPad equivalent on the iOS platform, and in
02:33fact that's even what Apple quote.
02:35If I bring up some Apple documentation from the Cocoa Fundamentals Guide,
02:40Apple themselves will say that foundation, AppKit and UIKit frameworks are
02:45essential to Cocoa application development, all other frameworks are secondary and elective.
02:51So Cocoa really does just become this generic term for using the Apple
02:55frameworks for building desktop applications and tangentially iPhone and iPad applications.
03:02Cocoa Touch doesn't even have a technical meaning.
03:05There isn't actually a header file for Cocoa Touch.
03:08But the benefit here is we don't have to worry about it.
03:11If I make a Cocoa App in Xcode, if I make an iPhone or iPad App in Xcode it will
03:16link to the things that I actually need.
03:19What I can then choose to do is link to other frameworks.
03:23Well how do I do that?
03:24Well, even in a basic Command Line tool like this, I can link to other frameworks.
03:29If I click on the Settings of my project, I make sure that I have the target
03:34selected and I jump over to Build Phases.
03:37What I will find here is this wonderfully phrased Link Binary With Libraries,
03:42meaning when it comes time to compile and build this application, are we
03:47reaching out to another framework?
03:49And in this case, yes we are Foundation.framework is the default here.
03:53If I click the plus button, it gives me a link of a whole bunch of other
03:57frameworks I can add.
03:58Now what you'll find is some of them end in the dot framework, they look like
04:02the little tool chest, others end in dylib which are Dynamic Libraries.
04:07You're more likely to be interested in the frameworks themselves, which really
04:10bundle up libraries with a bunch of other resources.
04:13Just browsing through them, I can also make a pretty good guess, as I'm sure you
04:18could about what they represent.
04:20We've got things like CoreVideo, CoreAudio, CoreMIDI, though some of them are a
04:25bit more vague, ApplicationServices for example, you might take a guess of what
04:30it represents, but I don't think anyone would bet money on it.
04:33It's all going to be driven by what you want your app to do. The thing is this.
04:39Your first step should never be just going out of framework.
04:43It should be go look in the documentation.
04:46So I cancel out of that, I jump into Help, and I jump to Xcode Help.
04:51Now we've used this primarily as a class references so far, and that's great for
04:56that but it's way more useful than that.
04:59The thing is when you start to search on terms that you don't know how to do,
05:02you want to do more with dates or strings, you want to work with audio or
05:06video or timers or something, you just start off by trying to figure out what's available.
05:11We type-in String and the first thing we're going to get is the Reference for
05:16things like NSString and Mutable string.
05:18Down in the System Guides is the really, really important stuff.
05:22You'll get things like the String Programming Guide.
05:25You will find a lot of different, very focused programming guides here available
05:29through the Xcode Help.
05:30We have got the String Programming Guide for Cocoa and now using Cocoa is a generic term.
05:36We could quite happily use this programming guide in just a regular Command
05:40Line foundation tool.
05:41If I search on date and time, we will find the Date and Time Programming Guide
05:46way more than just trading date objects but being able to work with calendars
05:51and formatting and so on.
05:53File management, be aware that sometimes the System Guides have a lot of results
06:00and here we've got over a hundred, but you'll find things like the File
06:03Management Programming topics.
06:06As you start to find some of these, what you can do is highlight one and then
06:09from the Editor menu, you can add a bookmark to it.
06:18That then gives you the bookmarks icon which will allow you to jump to your
06:21favorite documents, and if you can't find one of the programming guides or
06:27programming topics documents, this should be considered your first source of authority.
06:32Now when you're looking up information on something in particular, let's say I
06:36want to work with a timer.
06:37I want to figure out how to delay certain actions.
06:41I find that there is a class called NSTimer.
06:43I find that there is a System Guide for Timer Programming topics. It looks terrific.
06:47What you'll also often find is this section down at the bottom that says Sample Code.
06:52Unfortunately this is the one area I'm not such a big fan of, simply because
06:57there's a lot of old pointless stuff here in the Sample Code.
07:00If I look at all the results here, there is a whole bunch of things that look
07:04quite interesting, but clicking some of them, you're going to find let's say
07:08SonOfSillyBalls here, created back in 2003.
07:11I can assure you that this one is not going to be very useful to you.
07:16However more recent ones, particularly from say 2008-2009 onwards and
07:21particularly the iPhone-based ones can be very useful and good sources of
07:25information, but generally speaking, any programming guides that you can pick
07:30up, and even as a first three I'm very fond of those String Programming
07:34Guide, Number and Value and the Low- Level File Management, these are great
07:38sources of information.
07:40Let's say we did find something.
07:42I know that I want to work with say CoreAudio, playing back some music files.
07:47So I look at the Programming Guide.
07:50I find out the useful information here, and then I go back into my Project and
07:54say yes, I want to link to that framework.
07:57So I find in this case CoreAudio I click Add.
08:01Our project is now linking to that.
08:03However I can't do anything in my code until I do the Import statement,
08:10but until you use to what you're linking to, you want to take a look at your frameworks.
08:13I actually added this, let me just drag that into the Frameworks folder.
08:18just to keep it together.
08:19It doesn't really matter here.
08:20I will expand the CoreAudio headers, and I will see that there are several
08:24different ones AudioDriverPlugin, AudioHardware, CoreAudioTypes.
08:28If you find the header file with the same name as the framework, that's almost
08:32certainly the one you need.
08:33That will just import all the others.
08:35So I would come in here, #import> CoreAudio/CoreAudio.h. I'm using here the angle
08:46brackets not the quotes because this is not my code.
08:50It's system code, and of course once you've imported it, then the real work is going to begin.
Collapse this transcript
Goodbye
00:00Thanks for joining us for Objective-C Essential Training.
00:03You should now have a firm grasp on the core language features and feel pretty
00:06comfortable about taking those into more device-specific frameworks, things like
00:10iOS or desktop development.
00:13Take a look at the other courses of lynda.com that dive deeper into some of
00:16those areas of Apple development, and let us know if there's anything you would like to see.
00:19Good luck with your Objective-C programming.
Collapse this transcript


Suggested courses to watch next:

iPhone SDK Essential Training (2009) (6h 52m)
Simon Allardice


Xcode 4 New Features (1h 58m)
Bill Weinman


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked