Ok, so I know I promised you we’d look into some actual code, and now that we’ve gotten the formalities out of the way, I think you’re ready. Since packages and classes are the architectural building blocks of an application, it should be a fine place to start. So, without further adieu…
…don’t exist! Yeah, weird, huh? I bet you thought those folders in the Project Navigator were real, too. They’re not. They’re technically groups, and are just there as a virtual means of organizing your files. Take a look in the finder for yourself if you don’t believe me.
As a Flex developer, it’s kinda dirty. Sure, it also sucks if there’s naming conflicts. But hey, at least it’s one less thing for me to write about! Anyway, classes, unlike packages, really do exist. So let’s talk about them.
Classes in Objective-C typically come in pairs of two files, both carrying the same name as the class itself (by convention, anyway). They are the header file (i.e. MasterViewController.h) and the implementation file (i.e. MasterViewController.m). Sometimes there’s also *.xib files, but that’s technically a resource, so we’re not going to talk about that yet. So, what’s the difference between the header and the implementation? Well, the header is kinda like an interface, except not really, and the implementation is like the class itself, though it can also define an interface as well. Does that make sense? Hmm, let me try to break it down this way:
- The class header file, like interfaces in AS3, act as a reference for other classes to know how to interact with your class. When you establish dependency via importing classes, you do so via the headers. Also like interfaces in AS3, the header won’t actually contain any implementation logic. Unlike interfaces in AS3, however, the relationship is exclusively 1-to-1. If your intent is polymorphism, then you’d need to append a protocol to your interface. That’s a bit outside the scope of this lesson, though.
- The class implementation file contains all the stuff that other classes don’t need to be concerned about. The header file acts as a contract with other classes that guarantees that as long as they comply with it, the implementation will take care of the rest. (A quick side note: Objective-C implementation files use *.m, however if you see *.mm, that means there’s likely C syntax sprinkled in as well. You won’t have to worry about any of this for these lessons, however.)
Now, if you’re still feeling brave, let’s take a look at the MasterViewController.h file, shall we?
Looking at the Header File
Here’s what you should see:
#import <UIKit/UIKit.h> @class DetailViewController; @interface MasterViewController : UITableViewController @property (strong, nonatomic) DetailViewController *detailViewController; @end
Let’s break this down for a second. First, you have the import statement. Header files are typically responsible for importing the frameworks being used by the class. In this case, the master uses the UIKit.
Next, you have an @class declaration of DetailViewController. This is also like an import statement. Sorta. The @class is basically there to let the compiler know that you’re going to be referencing DetailViewController somewhere in the header file. You don’t have to declare references to anything that exists in the imported framework, so this is why DetailViewController is the only thing being listed here.
After that is the @interface declaration. This is really more like the declaration of a class you’d see in AS3. On the left side is the name of the class, and on the right is the name of the superclass. Also, if you squint your eyes, you might be able to see an open curly bracket, with the @end at the bottom being the close curly bracket, because everything in between is declared within the scope of the interface.
And by everything, I mean the property and method declarations. Like AS3, classes in Objective-C have properties and methods. In Objective-C’s case, public properties in the header files are prefixed with @property. Now, let’s talk syntax for a moment, because that really applies here.
In AS3, a simple datatype variable might be declared like so:
Meanwhile in Objective-C, that same variable would be declared like so:
In AS3, an object variable might look like this:
However in Objective-C, it would look more like:
Subtle, but it’s there. The asterisk in Objective-C is used to denote a pointer reference. Actionscript always did this behind-the-scenes, which is why whenever you edited an object in one place, it also got updated everywhere else that it was being referenced. (If you’re not familiar with pointers, I suggest you do some extra homework. They’re fairly prevalent in many different programming languages. Really, though, you just need to know that unless its a simple datatype, you need a pointer.) Now, if you look back at the property declaration in our code, you’ll see the same basic syntax as I described, asterisk and all. Finally, the keywords in parenthesis describe the characteristics of how the property gets synthesized into the class. See, it’s like this â€” @property is a shortcut in Objective-C that saves you the effort of writing your own setters and getters, much like how you might list a public property in AS3. However, Objective-C still needs more information in order to generate this code for you. In this case, whether the property is atomic or nonatomic, and whether its strong or weak. Now the strong or weak part you should recognize: It’s the same as weak referencing with event handlers. Basically, strong increments the instance’s internal reference counter, while weak does not. Atomic and nonatomic is a bit more complex, and has to do with multi-threaded applications. For efficiency reasons, we always use nonatomic when writing iOS apps. In case you were curious, here’s a list of other attributes you can use:
- readwrite - Uses both a getter and setter for the property. Enabled by default.
- readonly - Uses only a getter.
- copy - Clones whatever object gets passed to the setter.
- assign - Basically the same as weak referencing. This is what you’d use if you didn’t enable automatic reference counting in the first lesson. (This is also what you’d use if you were working with an older version of Xcode.)
- retain - The counterpart to assign, this is the same as strong referencing. Also used if you didn’t enable automatic reference counting.
Whew, that covers it for the header. Now, let’s take a look at the implementation.
Looking at the Implementation File
Open up MasterViewController.m and you should see something like this:
#import "MasterViewController.h" #import "DetailViewController.h" @implementation MasterViewController @synthesize detailViewController = _detailViewController;
Like with the header, the top of the file begins with the imports. Here, you’re going to want to list every custom class that is being used in the implementation, as well as the class’s own header file. You might notice the syntax is slightly different. When importing, frameworks use <>, while class headers use “”. Next, there’s the @implementation line. Just like with @interface, imagine this as being the open curly bracket that wraps everything down to the @end.
Below the implementation is @synthesize. This is where you list all the properties declared in the header. Also, remember when I said @property is a shortcut to getter/setter? Well, normally when you write getters and setters, you would need a private property to store the value in, right? In this case, @synthesize is stating that this property would be called _detailViewController. Unless you’re overwriting the default getter/setter, though, you probably shouldn’t ever need to use _detailViewController beyond this line.
This pretty much covers the introduction to classes in Objective-C. There’s obviously a lot more to talk about still, but I’d like to dedicate methods to its own lesson, as its syntactically the strangest part of Objective-C. (Really, it’s very strange. Run now while you still can!)
March 2014 M T W T F S S « May 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31