Cocoa 101: Object-Oriented Programming for the Masses – Part 2

Welcome back to Part 2 of Cocoa 101: Object-Oriented Programming for the Masses! I received a lot of great feedback on my previous article, and I’m looking forward to sharing with you once again what I’ve learned about Cocoa and the Objective-C language. If you missed Part 1 of this tutorial, read it here.


To start off Part 2, I’d like to take just a brief moment to explain why I picked this title (Object-Oriented Programming for the Masses) for my article. I believe that Cocoa is the easiest and most logical method of GUI-based, object-oriented application programming available in a mainstream operating system. While many programming experts have welcomed Cocoa with open arms because of its RAD (Rapid Application Development) qualities and powerful foundation classes, I see its major strength as being a window of opportunity for regular “Joe” users with some technical computer skills to “make the leap” and become software producers, not just software consumers. And no, I’m not just talking through my hat. The amount of innovation I’m seeing right now in the Mac OS X software community is staggering, and much of it is coming from people who have slowly grown into the role of being a software developer, not people with 20+ years experience in programming and boasting several degrees in computer science. Though the fruits of my own labor have yet to be shown to the public, slowly but surely I find myself growing into the role of software developer as well. And I can easily claim that Cocoa is the reason, the only reason, that this has occurred.


Now if you’ll recall, last time I introduced you to a few of the basics of Objective-C. In particular, the fact that every Objective-C object belongs to a class. Also, I stated that the concept of encapsulation is important in object-oriented programming — that is, the implementation of an object is hidden behind its interface. That’s where I left off previously, and that’s where we’ll pick up the trail this time.


In spite of all that was presented in Part 1, I missed showing you one very important thing: exactly how to define a class in code. This is because it’s best to know a bit more about Cocoa before you can understand how that process works. So I’ll use this opportunity to introduce a few of the basics of the Cocoa framework, as well continue on with our exploration of Objective-C.


Remember, every Objective-C class features at least one of these attributes: class methods (for the class objects), instance methods (for the regular object instances), and instance variables. So how exactly is a class definition created? Objective-C typically follows the grand C tradition of splitting up groups of code (in this case, objects) into two files: a header file and the actual code file. In Objective-C, this usually translates as: the interface file and the implementation file. For example, a MyPerson class would be defined using two files: MyPerson.h and MyPerson.m. The .h is the standard C header extension, and the .m stands for “Objective-C code module”.


Let’s create this MyPerson class right now, which we’ll use as an example object for the duration of this article. I’ll pretend that objects can do anything in the world, just to make things fun. Say you want to store a few details about a person in a MyPerson object. This object should store information for the person’s full name, address, date of birth, and hair color. You also want to be able to send this person a postcard with your name and return address on it along with a message. (I told you objects can do anything!) The interface file (MyPerson.h) might end up looking something like this:


#import <Cocoa/Cocoa.h>

@interface MyPerson : NSObject {
NSString *fullName;
NSString *address;
NSCalendarDate *dateOfBirth;
NSColor *hairColor;
}

// Accessor methods
– (void)setFullname:(NSString *)newName;
– (NSString *)fullname;
– (void)setAddress:(NSString *)newAddress;
– (NSString *)address;
– (void)setDateOfBirth:(NSCalendarDate *)newDate;
– (NSCalendarDate *)dateOfBirth;
– (void)setHairColor:(NSColor *)newColor;
– (NSColor *)hairColor;

// Other methods
– (void)sendPostcardWithMessage:(NSString *)message toAddress:(NSString *)address
fromName:(NSString *)name returnAddress:(NSString *)returnAddress;

@end


Makes sense? No? Well, we’ll soon get to the bottom of it. The first line is an import “complier directive”. A compiler directive tells the software compiler what to do before processing your code. In this case, it’s saying to import the main header file for the Cocoa framework. Cocoa is actually made up of two “kits”, the Foundation Kit and the Application Kit, but Cocoa.h imports them both. I’ll explain some of the differences between the two kits in a little while.


The next line is where the Objective-C interface starts for your object. The interface declaration is indicated by the @interface bit of code and ends where @end is located (i. e., at the bottom of this file). After @interface we have the name of the class (MyPerson). Then there’s a colon followed by the name of the class that MyPerson inherits from. Since MyPerson doesn’t require any specific functionality offered by any particular Cocoa class, we’re just inheriting from the root object, i. e., NSObject.


Now we’ve arrived at the spot where your object’s instance variables are declared. Right after NSObject is an open curly brace. From here on until the close curly brace, all of the object’s instance variables are declared. Now instead of using standard C types such as char (for strings), int, etc., we’re opting to use data objects from Cocoa’s Foundation Kit. There are many reasons to use Cocoa data objects rather than simple C types, not the least of which is that these objects come built-in with a ton of functionality that will prove to be very useful in any project you build.


So here I’m declaring the instance variables fullName and address to be of the class NSString (which is, of course, Cocoa’s default string class for storing text). Now why don’t I just declare these variables as being of type id? After all, since Objective-C supports dynamic typing, all objects can always be declared using the id type. Well, while that’s true, it’s a good idea to “statically type” variables whenever possible because (a) the compiler will warn you if you’re trying to send messages to an object that probably aren’t supported by that object, and (b) it shows visually (to the programmer) what kind of class the object belongs to.


With that out of the way, we’ve come to the last two instance variables: dateOfBirth and hairColor. dateOfBirth belongs to the NSCalendarDate class. NSCalendarDate is an object that represents a point in time in the context of the standard western Gregorian calendar. NSCalendarDate is actually a subclass of NSDate, which represents a more low-level interface to time. I’ve chosen to use NSCalendarDate because that class provides lots of groovy methods that return useful bits of data, such as dayOfMonth or minuteOfHour and the like. The last variable, hairColor, belongs to the class NSColor. NSColor actually is part of Cocoa’s Application Kit, because colors aren’t usually used outside of the context of a visible application (as opposed to a background process or something like that). NSColor is an object used to represent a color defined in a color space (usually the standard RGB color space of computer screens). The nice thing about NSColor is that it provides a lot of handy class methods such as brownColor, redColor, greenColor, etc., that allocate and initiallize an NSColorobject and hand it back to you with the proper color values already set. Cool, huh? Of course, most people don’t have green hair, but they might have a green car or even a green house!


Now we’re on to the accessor methods. I mentioned in Part 1 that accessor methods are the preferred way to allow other objects to access or modify your object’s instance variables. Here, we have a pair of accessor methods for each variable. So for the fullName variable, we declare two methods: setFullName: and fullName. setFullName: is interesting, because it’s the first time I’ve presented an Objective-C method with an argument. Objective-C differs from some other object-oriented languages in that it uses named arguments. In other words, each variable that you pass on to a method has a name before it. All of these names comprise the full name of a method, also known as the method’s signature. This results in the fact that you can have more than one method that starts the same way. For instance, in addition to the setFullName: method declared, we could declare a setFullName:maidenName: method. It might look like this:


– (void)setFullName:(NSString *)newName maidenName:(NSString*)newMaidenName;


Note that the names of the actual variables contained in the method declaration aren’t part of the method’s signature. In fact, those names could be anything. The line above would mean absolutely the same as this:


– (void)setFullName:(NSString *)abc maidenName:(NSString *)xyz;


OK, so now you know a bit more about methods and their arguments. Most of the time, however, simple accessor method pairs simply feature a “set” method with one argument (the new value, or object, to be assigned to the instance variable), and a “retrieval” method that’s simply the name of the instance variable and uses that variable as it’s return value. Now this convention of having two accessor methods like that (“setBlahBlahBlah” and “blahBlahBlah”) isn’t simply around just for kicks and grins. It actually comes in very handy in several cases because some of the more complicated Cocoa design patterns automatically assume that your objects feature accessor methods declared in that manner. So it’s usually a very good idea to stick to the convention, unless there’s some amazingly overriding reason to do so.


Believe it or not, we’re almost done with the interface file! After all of the accessor methods, we have only one “non-standard” method declared: sendPostcardWithMessage:toAddress:fromName:returnAddress:. Whew! That’s a pretty long method signature, with four arguments no less! This method allows us to tell a MyPerson object to send a postcard with a certain message to a certain address and specify the name of the person who sent it and also that person’s return address. Because of the named arguments, the usage of this method is self-explanatory. It wouldn’t be as clear in some other computer languages. So let’s say that in another object, you’ve created a MyPerson object and assigned it to the variable janeDoe. You might send it a message like this:


[janeDoe sendPostcardWithMessage:@"Hi! Wish you were here! Bye!" toAddress:@"1234 Cherry Lane, Bigtown, CA 98765" fromName:@"Joe Smith" returnAddress:@"192 Hotel Drive, Paradiseville, HI 91827"];


Wordy, but very understandable. If you’re wondering what all those “@” signs are before the quoted text, that’s a special compiler directive that says “create an NSString object containing the following text”. It’s the easiest way to create Cocoa strings, and you’ll find yourself using it almost everywhere all the time.


With the MyPerson interface out of the way, we arrive at the implementation file: MyPerson.m. Let’s take it bit by bit this time. The first bit might look like this:


#import “MyPerson.h”

@implementation MyPerson

– (id)init
{
self = [super init];
if (self) {
fullName = @””;
address = @””;
dateOfBirth = [[NSCalendarDate calendarDate] retain];
hairColor = [[NSColor clearColor] retain];
}
return self;
}


The first line is an import directive that says to import the counterpart header file where the object’s interface is declared. If the interface weren’t imported, then the object implementation wouldn’t know what the heck it’s implementing!


Next we have a simple init method. As presented in Part 1, the first order of business to send a message to the superclass (NSObject) to initialize the object, and the returned object pointer is assigned to self. Now the next step (if (self) {) is theoretically optional. It’s very unlikely that the NSObject initialization process will fail, but, just in case, we’ll start assigning values (we’ll call them values, but they’re really only pointers to objects containing values) to the instance variables only if self equals anything other than nil (nil is an Objective-C data type representing a null pointer, a “non-object” if you will).


We then assign blank NSString values (really, pointers to the newly-created string objects) to fullName and address. dateOfBirth is assigned an NSCalendarDate value representing the very point in time when that statement is executed. In other words, “now”. The hairColor variable is assigned an NSColor value representing a no color value (a clear color). Note that both of these messages are each nested in a retain message. You’ll learn all about that in a moment. Hmm, when you sum it up, basically this person has no name, no address, was just born, and has transparent hair. Pretty freaky, isn’t it?


But wait! That’s what the accessor methods are for: to assign “real” values to these variables! Here’s the code for them:


– (void)setFullname:(NSString *)newName
{
[newName retain];
[fullName release];
fullName = newName;
}
– (NSString *)fullname { return fullName; }

– (void)setAddress:(NSString *)newAddress
{
[newAddress retain];
[address release];
address = newAddress;
}
– (NSString *)address { return address; }

– (void)setDateOfBirth:(NSCalendarDate *)newDate
{
[newDate retain];
[dateOfBirth release];
dateOfBirth = newDate;
}
– (NSCalendarDate *)dateOfBirth { return dateOfBirth; }

– (void)setHairColor:(NSColor *)newColor
{
[newColor retain];
[hairColor release];
hairColor = newColor;
}
– (NSColor *)hairColor { return hairColor; }


Looks scary, doesn’t it! What’s with all that retain and release jargon? Only one of the most important concepts to understand about the Cocoa framework: memory management. The bane of the programming world, memory management is one of those things that most people just wish they could ignore and forget about. And, in some languages, fancy run-time engine techniques such as “garbage collection” really do allow people to forget about it most of the time. While Cocoa doesn’t use garbage collection, it uses another kind of memory management that is by all accounts pretty simple as well, and it’s typically called “retain and release”. This is how it works:


Object A (we won’t discuss how Object A was created) allocates and initializes Object B. Object B automatically starts out with a retain count of 1. In other words, Object B is retained by Object A. Now let’s say that Object A no longer needs to use Object B, maybe because Object A was “deallocated” (in other words, it no longer exists in memory). What happens to Object B? I’m afraid it just sits around in memory forever (or until your application quits) and is completely useless because there are no more pointers to it anywhere in your application. This is called a memory leak, and memory leaks are bad because lots of big memory leaks will drastically slow down the host computer and make your users angry. And angry users are to be avoided at all costs, believe me.


What needs to happen is that Object B is released when Object A no longer needs to use it. This is what the [objectB release]; code is for. Releasing an object doesn’t automatically deallocate it however. An object is deallocated only when its retain count goes down to 0. When an object has a retain count of 1, and it’s sent a release message, its retain count will change to 0 and it will be deallocated. But what if there’s another object, Object C, that is passed a pointer to Object B from Object A? What if Object A releases Object B, and then Object C tries to use Object B? What will happen? Your application will crash. Crash and burn, baby. That will make your users even more angry, and you wouldn’t want that! So, basically, Object C should send a retain message to Object B so that it will still be in memory when Object A releases it. In other words, Object B’s retain count will go up to 2, so that when it’s released by Object A, its retain count will go down to just 1 and it will still be in memory and available for use.


So, you see, it’s really quite simple. Every object initialization or retain message should be balanced by a release message. In other words, 1 + 1 + 1 – 1 – 1 – 1 = 0. There’s a catch here, however. Sometimes you’re going to lose a pointer to an object before you have had a chance to release it (maybe because you bypassed assigning the pointer to a variable). Sometimes you’re going to create an object and then immediately pass the pointer along to another object that isn’t guaranteed to release the object. In these cases, there is no clear solution based on a simple release/retain mechanism. That’s why Cocoa provides an ingenious solution: an autorelease pool. The idea is that a “third-party object” (an autorelease pool) will retain an object for a short period of time (normally one loop of an application’s “event cycle”) and then release it. These kinds of objects are usually considered “temporary” objects, that is, they are used in situations where objects need to be used only for a short period of time. The way you autorelease an object (i. e., add it to the current autorelease pool) is simply by sending it an autorelease message rather than a release message. Let’s break this down again:


Object A creates Object B (which has a retain count of 1), then autoreleases it and hands it over to Object C, which uses it in just one method. Shortly after that method has been executed, the autorelease pool sends Object B a release message which brings the retain count down to 0 and Object B is deallocated.


The really nice thing about the autorelease pool is that if an object’s retain count is above 1, then it won’t be deallocated when the autorelease pool sends it a release message. So you can autorelease an object with a retain count above 1, knowing that it won’t be deallocated prematurely. And you can send an object a retain message after it’s been autoreleased, so that it will be usable after it’s been released by the autorelease pool. That’s actually something to be very careful about when using autorelease pools: you don’t want an object to be released by the autorelease pool before you’re done using it, because then your application will crash. So always retain an object if you want to make sure it won’t be autoreleased before you’re done using it.


By the way, you might be interested to know that autorelease pools are actually Cocoa objects belonging to the class NSAutoreleasePool, and you can create more than one autorelease pool during the duration of your application. However, regular GUI-based Cocoa applications have a default autorelease pool created automatically, so you don’t have to worry about creating one yourself.


Going back to MyPerson‘s accessor methods, you can see that each of the “set” methods sends a retain message to the new object, sends a release method to the old object, and then makes the instance variable point to the new object. Notice the retain, then release order here. This is the best order, because if the object being pointed to by the method argument is the exact same object that the instance variable points to, it’s retain count will just go up 1 and then down 1, which is like nothing happened. Think what would happen if the object were released, then retained. If it were released with a retain count of one, it would be deallocated, and the retain message would then be sent to a invalid piece of memory, causing your application to crash. So retain, then release, is the only order that can be used if you use this style of coding (there are, in fact, several other methodologies different people use to get around this problem, but I personally like the one outlined above the best).


One more thing that I’d like to mention is, if you look back at the init method for MyPerson, you’ll see that the new date and color objects are both being sent a retain message. Why? Well, the convention in Cocoa is that any “convenience” class methods that automatically allocate and initialize an object for you also autorelease the object before returning it. So, if you want to make sure the object isn’t deallocated when it’s released by the autorelease pool, you have to send it a retain message, which is what we’re doing in our init method.


Now the accessor methods which are for retrieving a value are considerably easier. They fit on just one line, in fact, because all the code does is return the value. Easy, no?


Here we come to the final bit of code for the MyPerson implementation:


– (void)sendPostcardWithMessage:(NSString *)message toAddress:(NSString *)address
fromName:(NSString *)name returnAddress:(NSString *)returnAddress
{
// send postcard code goes here
}

– (void)dealloc
{
[fullName release];
[address release];
[dateOfBirth release];
[hairColor release];
[super dealloc];
}

@end


See that @end at the end there? That tells the compiler that your implementation code has ended. Good thing too, because we don’t want this article to get too long! All kidding aside, there really isn’t too much going on here. Obviously, I haven’t implemented the send postcard code because, well, that would be quite a feat, wouldn’t it? Moving right along to the dealloc method: this method is called automatically by the NSObject class itself when the object’s retain count has gone down to 0, allowing you to take care of any “cleanup” needed before the object is deallocated. Since we want to be good citizens, we’ll release all of our instance variables before the object is deallocated. We also don’t want to forget to allow the superclass to get its cleanup work done too, so we’ll send it a dealloc message at the end.


So there you have it. A more-or-less fully complete Objective-C class that employs several other Cocoa classes. Where do we go from here? I think this would be a good time to give a brief overview of what actually is in the Cocoa framework and what tools Apple makes available to use in creating Cocoa applications. Then I’ll wrap up Part 2 by giving you a few more Internet resources to check out as well as some books that I’ve found to be very valuable.


As I’ve said before, the Cocoa framework is made up of two “sub-frameworks”, or kits known as the Foundation Kit and the Application Kit (Apple now calls the Foundation Kit just “Foundation”, but I prefer to call it the Foundation Kit). Why the two kits, rather than twenty, or one? Generally, the Foundation Kit contains all the basic data classes, classes that enhance the Objective-C language, and classes that allow access to low-level system services. The Application Kit contains all high-level application services classes, all the view (GUI) classes, multimedia services classes, and additional data classes (like color classes).


So how many classes are in these kits? Lots, and when you put them to work, they will save you a huge amount of precious time which would be better spent building the real guts of your application. The Foundation Kit contains classes for many different types of values (numbers for instance), strings (there are a number of classes that provide nifty ways of storing and manipulating text), binary data, dates, and even time zones. Another group of classes that are very useful are the container classes, such as arrays (similar to regular C arrays, these objects “contain” multiple objects ordered by number), dictionaries (objects that allow access to contained objects via associated key objects), and sets (which contain multiple, unique objects in an unordered fashion). Other classes include a file manager, a notification center (notifications are used all over the Cocoa framework; they allow you to easily broadcast different types of messages to any objects that have registered themselves with the notification center to receive those types of messages), a timer (an object that will send a message repeatedly at certain intervals to any object you specify), and many more.


The beautiful thing about the Cocoa data classes is the easy yet extremely powerful way in which they can save and open files. For example, you can create a string object, put some text in it, send it one single message, and poof! A text file is saved on your hard drive. Loading a text file back into a string object is similarly a no-brainer. But it gets even better. You can add a bunch of standard data objects to an array object, sent it a save message, and it will actually generate an XML-based “property list” file containing an entire tree structure of your data objects. You can nest the objects too: put some string objects in an array object, put that array object along with some other objects in a dictionary object, put that dictionary object along with another array object in another dictionary object, and then save that dictionary object. It will all be saved as a human-readable XML file that can be parsed using any XML parser on the planet. This method of data storage is so easy to use, so open, and so seamless that most Cocoa developers use it all the time, even Apple. In fact, Safari uses a property list file to store all of its bookmarks, and iTunes and iPhoto export a copy of their data libraries as property lists so that all the new iLife applications can access each other’s data. The default format for storing application preferences is an XML property list as well.


Now what about the Application Kit? What kind of groovy things can we find there? How about windows, menus, buttons, sliders, tables, outline views, combo boxes, text boxes, rich text editors, toolbars, multiple-column data browsers, image views, and a whole lot more! The Application Kit is chock full of classes that are subclasses of the abstract class known as NSView. An abstract class is a class which, on its own, is fairly useless; it only does something interesting when it’s subclassed. NSView provides a clean and simple interface to the display of graphics. It doesn’t feature any drawing capabilities itself; it simply provides a “canvas” on which you can draw using other Cocoa classes. NSView is actually a subclass of NSResponder, which provides event handling such as for mouse and keyboard events. There’s also a number of classes which stem off of the NSCell class. Many view objects use lightweight cell objects to perform the actual drawing for display and handling of events. Some view objects, like tables, use multiple cells at once. The Application Kit also contains numerous other classes which help with tasks such as printing, managing the clipboard, using standard interface elements such as Open and Save File panels, and the like.


That gives you a very rough idea of what kind of things you’ll find in the Cocoa framework. But, in the end, the main question is this: how do you actually create a Cocoa application? Apple provides two main tools: Project Builder and Interface Builder. Project Builder is an IDE (Integrated Development Environment) that you use to create and edit application projects. Cocoa is but one of the many programming frameworks supported by Project Builder, and you can use Project Builder to build applications written in standard C, Java, and other languages as well. Project Builder handles all of the mundane tasks of creating a basic Cocoa application, setting up a build process for compiling the application, loading up debugging tools, etc. for you. In fact, you can literally go into Project Builder, select New Project from the File menu, choose a folder to save it in, and then press the Build & Run button in the toolbar to run your new Cocoa application. A blank window will appear along with a menu bar that really works — all with you having written no code at all! Where does this window and menu bar come from? Read on…


Interface Builder, the other main tool I mentioned above, is one of the more brilliant aspects of the Cocoa development environment. Interface Builder allows you to access many of the Application Kit classes graphically. More to the point, it allows you to create the graphical interfaces for your applications and “hook up” your base application objects with your interface objects. Basically, what happens is that Interface Builder creates all these objects and “saves” them into a single package called a nib file (“nib” used to stand for NeXT Interface Builder, but now it just stands for nib). Just about every Cocoa application on the planet uses at least one nib file for storing all of the interface and related base objects. Nib files are loaded dynamically when your application is run, which means that all of the objects in the nib files are loaded into memory and are available for use. In some cases, all of the custom objects you use in your application can be loaded from a nib. Applications can also dynamically load nib files stored in “bundles” while the app is running, which lets you create an entire plug-in architecture for your application with a minimum of hassle.


So to answer the question of where does the window and menu bar of a brand new Cooca application come from: it is loaded from the default nib file that Project Builder automatically generates. Project Builder and Interface Builder are somewhat integrated; they can talk to each other and cooperate on how your project’s code and its interface are glued together. I won’t go into all of the details here, but, suffice it to say, you’ll be toggling back and forth between Project Builder and Interface Builder a lot while developing Cocoa applications.


And now, at long last, we arrive at the end of Part 2 of Cocoa 101: Object-Oriented Programming for the Masses. I’m very pleased to see that you’ve made it this far and that you’ve found Cocoa to be an interesting and hopefully exciting technology. I also hope that you have indeed learned a bit about what Cocoa is, what it can do, and the basics of how Objective-C works. I’m happy to report that all of the concepts presented in parts 1 and 2 of this article series constitute the basis of what it means to be a Cocoa developer, and you will find that just about everything you learn about Cocoa in the future will simply be building upon these core concepts.


I haven’t quite decided yet if I should write a Part 3 for Cocoa 101, because, in a sense, Apple and many others have already written Part 3. Apple provides some excellent Cocoa development tutorials and more detailed overviews of the Foundation Kit and Application Kit on the Cocoa Documentation Web Site, and there are numerous other Web sites and books which feature documentation, tutorials, and sample code for you to play with and tweak. In addition to the links I presented in the previous article, here are some more resources you should definitely check out (if I’ve overlooked anything, please forgive me!):

Web Sites & Mailing Lists


Stepwise
I was much remiss to leave Stepwise out of my earlier list of sites. Stepwise has been providing a valuable online resource for NeXTSTEP/Cocoa/WebObjects developers for over nine years (!) now and contains many great articles targeted at both beginners and advanced developers alike. Incidentally, Stepwise is run by Scott Anguish, co-author of one of the best Cocoa programming books currently available (in my humble opinion). See below for further details.


Omni Source Code
This is not for the faint of heart, but the Omni Group, a long-time NeXTSTEP/Cocoa developer, has made available a huge amount of source code in the form of several large and robust frameworks. The Omni frameworks have been used by many other third-party Cocoa developers, and it’s certainly worth taking a look at them and discovering all the many things they can be used for.


Cocoa Mailing List Archive
This site contains up-to-the-minute archives of both Apple’s Cocoa-Dev mailing list and the Omni Group’s popular MacOSX-dev mailing list. If you’re like me and you find receiving hundreds of geeky e-mails a day to be simply too daunting, then this site is for you. The search engine is an awesome feature as well.

Books


I’ve only purchased three Cocoa reference books so far, but there are several more than that on the marketplace now, so I’ll list all the ones I know about (or rather that Amazon.com knows about) here. I’ll put the ones that I actually have read at the top of the list along with a brief description.


Cocoa Programming for Mac OS X
by Aaron Hillegass of Big Nerd Ranch


This was the very first Cocoa book that I ever bought, and it helped me gain a solid understanding of what makes Cocoa tick, as well as presented many valuable good programming practices. Aaron makes fine use of real-world example projects to help you feel like you’re really accomplishing something, and his writing style is fun, yet philosophical. I would only knock it down to 4 stars out of 5 because I felt that a few of the more esoteric aspects of the Cocoa framework were somewhat overlooked. Then again, the book would have to be twice as big to cover everything, I suppose!


Cocoa Programming
by Scott Anguish, Erik M. Buck, and Donald A. Yacktman


This is the “mother of all Cocoa books”. Featuring over 1272 pages (!) of highly detailed information about nearly everything you could ever possibly want to know about Objective-C and Cocoa, this book is a must-have for anyone serious about Cocoa programming. The introductory sections on object-oriented programming concepts and design patterns and how they relate to the Cocoa framework are worth their weight in gold alone. While fairly technical in nature, I would say that any very enthusiastic beginner would appreciate what this book has to offer. I rate it 5 out of 5 stars!


Objective-C Pocket Reference
by Andrew Duncan


I bought this little guidebook because I knew that if I ever needed to remind myself of some Objective-C syntax and its usage, then this book would come in very handy. For what it is, it’s a great little resource.

Books I Wished I Had:


Cocoa Recipes for Mac OS X
by Bill Cheeseman


Learning Cocoa with Objective-C
by James Duncan Davidson


Building Cocoa Applications: A Step by Step Guide
by Simson Garfinkel and Michael K. Mahoney


Cocoa Programming for Dummies
by Erick Tejkowski


Cocoa in a Nutshell (coming soon)
by Michael Beam and James Duncan Davidson


About the Author:
Jared White is President and Art Director of Web site and graphics design company GaelDesign. He is also Editor-in-Chief of The Idea Basket, an e-zine featuring provocative news commentary, articles, editorials, and reviews related to software and interface design, the Internet, multimedia, and technology. Jared became a PC-to-Mac switcher in 2001 and has been having a blast with Cocoa ever since. He can be reached via e-mail at [email protected].

24 Comments

  1. 2003-05-07 8:00 am
  2. 2003-05-07 8:28 am
  3. 2003-05-07 8:45 am
  4. 2003-05-07 9:21 am
  5. 2003-05-07 10:27 am
  6. 2003-05-07 10:38 am
  7. 2003-05-07 11:26 am
  8. 2003-05-07 12:07 pm
  9. 2003-05-07 12:15 pm
  10. 2003-05-07 1:21 pm
  11. 2003-05-07 1:25 pm
  12. 2003-05-07 2:50 pm
  13. 2003-05-07 3:48 pm
  14. 2003-05-07 4:00 pm
  15. 2003-05-07 4:02 pm
  16. 2003-05-07 4:05 pm
  17. 2003-05-07 4:59 pm
  18. 2003-05-07 5:03 pm
  19. 2003-05-07 5:18 pm
  20. 2003-05-07 5:36 pm
  21. 2003-05-07 5:43 pm
  22. 2003-05-07 7:41 pm
  23. 2003-05-07 9:05 pm
  24. 2003-05-08 9:41 am