05.01.2013 Views

Mac OS X Leopard - ARCAism

Mac OS X Leopard - ARCAism

Mac OS X Leopard - ARCAism

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

492<br />

CHAPTER 26 MAC <strong>OS</strong> X DEVELOPMENT: OBJECTIVE-C<br />

The only difference, of course, is that the factory method produces an autoreleased instance,<br />

whereas the manually allocated method does not.<br />

NOTE Why bother with factory methods? There are some edge cases where they are useful.<br />

Singleton optimizations are one. Teaching people how to write class methods is another.<br />

Mostly, though, it’s just a way to save three lines of code. For something you aren’t using<br />

much, it isn’t worth the hassle, but if it’s something you use a lot, the savings add up. The foundation<br />

classes, such as NSString and NSArray, are lousy with factory methods. If you multiply<br />

three lines of code by the number of times you instantiate NSArray, we’re talking thousands of<br />

lines of code. That is why it’s commonly said that Objective-C programmers hate code.<br />

Init and Dealloc<br />

With the class methods implemented, it’s time to fill out the instance methods. The first method<br />

declaration you come to looks unfamiliar:<br />

- (id)init;<br />

A quick visit to the interface reveals no such declaration. Veterans of object-oriented programming<br />

are sagely nodding right about now. The init method was inherited from the<br />

superclass, NSObject.<br />

TIP In Xcode, you can switch between a class’s interface and its implementation with the keystroke<br />

Cmd+up arrow.<br />

During the instantiation of an object, you actually call two methods. The first, alloc, is sent<br />

to the class you want to instantiate. This returns an object—you hope an instance of the class<br />

you just called. However, the object is in a dangerous state. Its instance variables have been<br />

declared, but any pointers are not actually pointing to anything. Dereferencing or messaging a<br />

floating pointer will cause any program to immediately crash. As such, you immediately call the<br />

new object’s instance method, init.<br />

If a superclass implements a method, you can call the method on any subclass, and the<br />

superclass’s implementation will be found and executed. However, if that subclass also<br />

implements the method, the subclass’s implementation will be used instead. In object-oriented<br />

programming, you say that the subclass’s implementation overrides the superclass’s implementation.<br />

Sometimes that’s what you want, but sometimes you just want to add something to the<br />

superclass’s method, rather than replacing it outright. To accomplish this, you call the superclass’s<br />

implementation from within your own. You do this by sending a message to the superclass<br />

via the keyword super.<br />

In Objective-C, as with any language, there are implied contracts. For example, nothing in<br />

the language is going to force you to call init right after alloc. You just have to do it to make<br />

things work right. Another implied contract is that if you override init, you have to call super,<br />

and if that call fails for some reason, you have to return nil. Since nil is equal to the Boolean NO,<br />

we can do so with a simple if statement.<br />

if (![super init])<br />

return nil;<br />

Only then are you safe to do your own initialization, setting your name pointer safely to nil:<br />

name = nil;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!