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

There are two major varieties of Cocoa available. The first variety, possibly the more well known of the two, is the kind that you can use to make a nice warm cup of chocolate milk. While tasty, it’s hardly proper subject matter for an operating systems information site. The second variety is far more on-topic: a programming environment for Apple Mac OS X that is the modern evolution of of the original NeXTSTEP frameworks. That’s what I’m here to talk about today.

Before I go on, let me give you a brief background of my programming experience. Up until I really started using Cocoa, I was what you could call a bona fide dabbler. I dabbled in Basic for a long time, starting with Microsoft’s Basic interpreter for the Commodore 64, graduating to GWBasic and QBasic in MS-DOS, and ending up using Visual Basic under Windows. I dabbled in C for a while, but didn’t get too far because, frankly, I wanted to create cool little Windows productivity apps and, for that purpose, C, or even C++ at that time (mid-90’s), was a major headache for a simple programming hobbyist like myself. After a while, I dropped out of programming altogether, focusing instead on Web graphics and HTML development (as well as electronic music, but that’s a whole other story).


What brought me back into application development was my Web design business. I tried hard for a long time to ignore the inevitable: I couldn’t rely on building Web sites using static HTML files alone for much longer. The Web was just becoming too big and too sophisticated, and large sites were taking too long to create. So I started looking into Perl. It was easy enough to take existing, open-source Perl packages and mess around with them, but it didn’t take long for me to discover that it wasn’t what I was looking for. Then I found out about PHP, and I was thrilled. Now here was a language I could get behind, because it was super-easy to embed some bits of code into HTML files and include other bits of code and HTML into those files dynamically. So I really jumped onto the PHP bandwagon, and since then I’ve heavily customized several open-source content management systems as well as developed a simple online ordering system for my Celtic band web site.


Which brings me up to the turning point in my programming escapades. Around the time I started working with Perl and PHP, I bought my first Mac, a PowerBook G4. This was two years ago, right after the first version (10.0) of Mac OS X was released. I loved Mac OS X instantly, and I became a PC “switcher” before it was the cool thing to do. While exploring the innards of this strange new UNIX-based Mac OS, I discovered Cocoa. I was long been wishing that I could get back into real end-user desktop application development, but I didn’t want to use a “simple” environment such as RealBasic (the Mac’s answer to Visual Basic). Plus, I had grown quite fond of the C-style syntax of Perl and PHP. Reading up on Cocoa, I found out that it was an object-oriented framework with a clean and elegant design built using the Objective-C language, and that it had been the official development environment for the NeXTSTEP OS which Apple had purchased back in 1997. Bottom line: it was solid and robust and had been worked on for many years. It had proven itself as a viable method of rapid, modular application development, and Apple had deemed it worthy enough to make it the de-facto standard for next-generation development on the Mac. So I decided to bite the bullet and learn how to program in Cocoa, and thanks to Apple’s brilliant move of bundling best-of-breed development tools with the OS for free, I could build my own apps without having to pay a single cent.


Which brings us to the present day. Now you can see where I’m coming from as a programmer: someone with a decent amount of experience in lightweight RAD languages and Web scripting languages. Most Cocoa programming guides expect you to be an expert in C or C++ programming, which I most certainly am not, so it took me much longer to wrap my head around some of the more difficult language constructs of Objective-C than it might someone else. Now that I feel that I’m at least at a knowledgeable intermediate level with Cocoa, I want to present some of the basic concepts of the environment to other people interested in Mac OS X programming (or Linux/BSD if you use the open-source clone of Cocoa called GNUStep) in a way that makes it easier to understand for “newbies” and people with experience in only simple scripting languages. However, I’m assuming that you have at least some very basic knowledge of programming concepts such as variables, data types, functions/subroutines, statements, etc., since discussion of those topics is beyond the scope of this article.


To start off with, we have to remember that Objective-C is a language and Cocoa is a framework — i. e., a collection of objects and functions that provide all the basic building blocks necessary to create a fully-featured GUI-based (or command line based) application. While Cocoa is built using Objective-C, other languages such as Java (or even Perl or Python) can be used to build Cocoa apps. But Objective-C is the default, and in many ways, the preferred language to use.


Objective-C is a beautiful language. While it is a superset of C, which means anything you can do in C you can do in Objective-C, the reality is that the Cocoa frameworks eliminate the need to use many of the standard C data types and library functions. Cocoa provides powerful objects for storing and manipulating strings, arrays, hashes, and many other common data types, and also includes a number of useful structures such as points and rectangles for use in coding graphics routines. Cocoa objects take care of most of the hassles of memory management, leaving you to focus on the real task at hand: coding features. While you’re free to intermingle regular C code using standard data types and Objective-C code using Cocoa objects all you want, the preferred way to send and receive data from the GUI side of your application is through Cocoa data objects. The major exception to this is numbers: most Cocoa objects use standard C number types like int, float, and double, because they’re so simple and easy to work with.


There are a number of features to be found in Objective-C that can’t be found in C++. In fact, Cocoa couldn’t have been designed the way it was if NeXT had chosen C++ for its foundation. Objective-C is built around two core concepts: dynamic typing and run-time messaging (which embodies the secondary concept of dynamic binding). These concepts are mainly what sets Objective-C apart from its competitors.


Dynamic typing works like this: in Objective-C, an object identifier is a variable of type id. id is defined as a C pointer to an object stored in memory. This object can be of any type, or as the proper term is, it can belong to any class. It could be a Cocoa string object, or it could be a MyBigHouse object that you’ve created yourself. (If you don’t know what an object or a class is, don’t worry, it will all be explained shortly.) Since it isn’t determined until run-time, you have the ability to inspect the object and ask the object what class it belongs to before doing something with it. In a statically-typed language such as C++, you don’t have this kind of flexibility, since a variable always has to be of a certain type, even if limited “late-binding” functionality is available (a C++ thing).


Now in languages such as Perl or PHP, you simply call an object method much as you would a regular function. Not so in Objective-C. In Objective-C, you use messages. Basically, you send a message to Object A saying “do this”, and it does it. Methods are declared in a somewhat similar fashion to C functions, they can use multiple arguments, and they can return a value just like functions. In that case, the message is “Object A: do this and that and this and that and then give me back a response”. The distinction between calling an object method directly and sending the object a message instead is subtle but important. For instance, you may not know what kind of object you’re working with until run-time (because of dynamic typing), so how could the compiler know what method should be called ahead of time? Rather, because you’re sending a message, the Objective-C run-time engine looks up the appropriate method of the object and calls it on behalf of your code, and then passes the return value back to you.


The really neat thing about this is that you can ask an object if it responds to a “selector” (which is a special kind of variable containing an identifier that is linked with a method name), and then “perform” the selector on the object if that method is supported. So you don’t even need to know what kind of object you’re working with, just as long you can send it the right kind of message. You can even “save” a message and then use it later on, which is extremely important for Cocoa’s implementation of cross-application/cross-computer data communication, called “distributed objects”.


The Cocoa framework, while being very well organized, is very large and complicated, so I’ll save a lengthy overview of it for Part 2 of this article. But I’d like to get you up to speed on some of the very basics of the Objective-C language. I’m not going to get much into all of the philosophy and design principles of object-oriented programming right now. For that, I heartily recommend you read Apple’s excellent online book The Objective-C Programming Language. To sum it up, objects are nifty. Objects allow for “user-oriented” program design. Instead of designing the program’s architecture based on some arbitrary code organization only you will understand, you can design it around the intended feature set of the application. For instance, you can create a Person object, subclass it (more on that later) to make a JaredWhite object, and send it a writeCocoaArticle message. You can then tell it to notify you when the article is done, and when you receive its notification message, you can then send it a sendCocoaArticletoOSNews message and receive a yes or a no to determine if the transmission was successful. Objects also make reusing code easy, since an object only handles a specific, obvious portion of your application code, and in many cases is general purpose rather than specialized.


Now let’s down and dirty and start looking at code. Objective-C messages look like this (remember, in C, every statement ends with a semi-colon):


[anObject doSomething];


This line of code is telling “anObject” to “doSomething”. Or, more specifically, anObject is the receiver of the message “doSomething”. All messages in Objective-C are always enclosed in square brackets. This looks very different from C or C++, but it’s a simple, easy-to-read format once you get used to it. doSomething is the name of a corresponding method in the object, and is implemented like this:


– (void)doSomething {
// some code
}


This method doesn’t return anything, so its return value is of the “no value” C date type void. All the method’s code is contained within the braces, just like with a regular C function. The two forward slashes indicate that all the remaining text on the line is a comment, not code meant to be complied.


The minus sign before (void) indicates that this method is an “instance” method. If it were a plus, it would indicate that it is a class method. In Objective-C, each object belongs to a class. A class is a “blueprint” for object instances, and is actually initialized as an object itself by the Objective-C runtime. You can send this class object messages, but the only methods available are class methods as mentioned above. Basically, you can create as many instances of a class as you like, but there’s only one class object initialized by the Objective-C run-time ever during the execution of your app (so you don’t have to worry about it). In fact, you use a class object to create an instance of an object. The most common line of code to accomplish that is:


MyKindOfObject *myObject = [[MyKindOfObject alloc] init];


This code looks complicated, but it’s really very simple. The bit before the equals (=) sign says that the myObject pointer (remember, a pointer is a variable pointing to an object stored in memory, and you put a * before the variable name when you first “declare” it to indicate that) is going to be pointing to an object belonging to the MyKindOfObject class. The bit after the equals sign is a group of nested messages. Basically the way it works is that you can send a message to the object returned by a message. So the object returned by [MyKindOfObject alloc] is sent an init message. The alloc message calls the standard Cocoa alloc class method (also called factory method, since class objects can also be called factory objects because of their use as object instance creators). If you had written it yourself, you would have written it like this:


+ (id)alloc
{
// code to allocate memory and return an uninitialized object
}


Compare that method to the doSomething method above. This one has a plus sign, since it’s a class method and not an instance method, and it’s return value is an id, which means that it is a pointer to the object that was just created (note that you never put a * before id, because the fact that id is a pointer is already part of the data type).


Now back to that earlier message above. Outside of the [MyKindOfObject alloc] message, we see an [... init] message. Because alloc returns an uninitialized object instance, we have to send that object an init message to initialize it. init is a standard Cocoa instance method.


Once an object is initialized, it can be used for anything you like. Until then, it’s of no use to anyone. So remember, you first have to create an object by telling the class object to allocate the memory for a new object and return a pointer to that object, and then you have to tell that object to initialize itself. Although there are more ways to code that procedure besides the one I presented above (more on that next time), you should always keep this concept in mind.


Now you may be wondering something, and that is: where are all these “standard” Cocoa methods coming from? How is it that your custom objects can use them automatically? The answer is: inheritance, technically known as subclassing. Inheritance is one of the most important aspects of the object-oriented paradigm. The idea is that you start off with a single object class, called the base class or root class, and then every object ever created is a “subclass” of either that class, or any other class that is a subclass of that class. Many classes are subclasses of other classes which are in turn subclasses of another classes which are in turn subclasses, ad nauseam, going all the way back up to the base class.


In Cocoa, the base class is called NSObject. Every object created by Apple, you, or third-parties are going to be subclasses (either directly or indirectly) of NSObject. Again, going back to the above example. MyKindOfObject is a direct subclass of NSObject. You can also say that NSObject is the superclass of MyKindOfObject. The alloc class method and the init instance method are actually defined in NSObject, not your own class. However, you can change this behavior if you wish, because you have the power to override any method inherited from the superclass in your own class. In other words, you could write your own init method to ask another object for important information before completing the initialization process. In that case, your init method would be called instead of the superclass’ init method when another object sends your object an init message. But here we come to a dilemma. NSObject‘s init method contains all kind of special code to deal with memory management and other low-level stuff. If you override it with your own method, that code won’t get run. What do you do? Thankfully, there’s an easy solution. Objective-C provides two special keywords: self and super. self is a variable that points to the current object itself. super is a keyword that finds the superclass of the object and then points to it. So, if you wanted to write your own init method, you could do this:


– (id)init
{
self = [super init];
// custom code goes here
return self;
}


Here, you’re getting the initialized object returned by the superclass’ init method and assigning it to self. self must be returned at the end of the method, or your program will crash. But before you return self, you can do anything you like, including creating other objects and setting up instance variables. Which brings me to my final point. Objects are made up of not only methods, but instance variables. Instance variables are variables you can define for a class that you can use to store data internally in the object. For example, a Person object could have an instance variable called fullName, and another one called hairColor. These instance variables could be standard C data types, custom data types, or other objects, just like regular variables. Bear in mind that, by default, instance variables are only available to the object that defines them, and this behavior should very rarely be altered. However, objects commonly allow their instance variables to be changed or retrieved though the use of accessor methods, which I’ll explain in Part 2 of this article. Also, an important thing to remember is that every object instance has its own collection of instance variables. So one Person object’s fullName variable could contain a “Joe Brown” string and another Person object’s fullName could contain a “Mary Smith” string. This type of functionality, along with object methods, is what in object-oriented parlance is called “encapsulation”. That is, the implementation of an object (its methods and instance variables) is hidden behind its interface (the messages you can send to it). This allows for modularity, code reuse, and a whole bunch of other cool things. You’ll love it.



That’s it for Part 1, and it was quite a workout. You learned how Cocoa and Objective-C fit together, what an object is and what a class is, how to send objects messages, what methods and instance variables are, how subclassing works, and more. Next time, in Part 2, you’ll learn how to program an object’s interface and implementation (a very simple operation), as well as how to create methods that support one or more arguments (input variables), and then we’ll start delving into the Cocoa framework itself. Until then, I just want to reinforce the idea that Cocoa programming is really fun. It’s easier that it looks, and you can build amazingly-sophisticated programs with comparatively little effort. While some concepts can be difficult to master, nothing is so complex that it can’t be easily explained. While waiting for Part 2, I suggest checking out the following Web sites:


Apple’s Cocoa Documentation
http://developer.apple.com/techpubs/macosx/Cocoa/CocoaTopics.html


Cocoa Dev Central
http://www.cocoadevcentral.com


CocoaDev (a simply wonderful user-contributed WikiWikiWeb site)
http://www.cocoadev.com


Mike Beam’s Programming With Cocoa column at MacDevCenter.com
http://www.macdevcenter.com/pub/ct/37



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

56 Comments

  1. 2003-04-24 6:15 pm
  2. 2003-04-24 6:15 pm
  3. 2003-04-24 6:33 pm
  4. 2003-04-24 6:59 pm
  5. 2003-04-24 7:24 pm
  6. 2003-04-24 7:35 pm
  7. 2003-04-24 7:40 pm
  8. 2003-04-24 7:41 pm
  9. 2003-04-24 7:50 pm
  10. 2003-04-24 8:08 pm
  11. 2003-04-24 8:10 pm
  12. 2003-04-24 8:17 pm
  13. 2003-04-24 8:18 pm
  14. 2003-04-24 8:56 pm
  15. 2003-04-24 8:57 pm
  16. 2003-04-24 9:10 pm
  17. 2003-04-24 9:15 pm
  18. 2003-04-24 9:38 pm
  19. 2003-04-24 9:51 pm
  20. 2003-04-24 9:58 pm
  21. 2003-04-24 10:27 pm
  22. 2003-04-24 11:50 pm
  23. 2003-04-25 12:28 am
  24. 2003-04-25 12:31 am
  25. 2003-04-25 12:35 am
  26. 2003-04-25 12:52 am
  27. 2003-04-25 1:18 am
  28. 2003-04-25 1:32 am
  29. 2003-04-25 1:33 am
  30. 2003-04-25 1:43 am
  31. 2003-04-25 2:48 am
  32. 2003-04-25 3:09 am
  33. 2003-04-25 3:23 am
  34. 2003-04-25 5:21 am
  35. 2003-04-25 5:34 am
  36. 2003-04-25 6:21 am
  37. 2003-04-25 6:47 am
  38. 2003-04-25 7:46 am
  39. 2003-04-25 8:14 am
  40. 2003-04-25 8:34 am
  41. 2003-04-25 8:53 am
  42. 2003-04-25 9:20 am
  43. 2003-04-25 10:30 am
  44. 2003-04-25 1:36 pm
  45. 2003-04-25 2:59 pm
  46. 2003-04-25 3:53 pm
  47. 2003-04-25 4:16 pm
  48. 2003-04-25 5:35 pm
  49. 2003-04-25 5:46 pm
  50. 2003-04-25 7:15 pm
  51. 2003-04-25 8:45 pm
  52. 2003-04-25 9:24 pm
  53. 2003-04-25 9:51 pm
  54. 2003-04-26 1:40 am
  55. 2003-04-26 8:48 am
  56. 2003-04-26 2:11 pm