01.02.2014 Views

Objective-C Fundamentals

Objective-C Fundamentals

Objective-C Fundamentals

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.

116 CHAPTER 5 Creating classes<br />

It’s important to understand the two-step initialization process used by <strong>Objective</strong>-C<br />

because there are a number of nuisances that can appear subtle but jump up and bite<br />

you when you least expect it.<br />

BEWARE OF LURKING GOBLINS<br />

The code snippet that called alloc and init on separate lines has a silent but potentially<br />

fatal flaw. Although it may not be a problem with most classes (CTRental-<br />

Property included), it’s possible for init to return an object different from the one<br />

created by alloc. If this occurs, the original object becomes invalid, and you can only<br />

use the object returned by init. In coding terms this means you should always store<br />

the return value of init; here is a bad example:<br />

CTRentalProperty *newRental = [CTRentalProperty alloc];<br />

[newRental init];<br />

And here is a good example:<br />

CTRentalProperty newRental = [CTRentalProperty alloc];<br />

newRental = [newRental init];<br />

Rather than worry about handling such scenarios, it’s generally easier to perform both<br />

steps at once, as in [[CTRentalProperty alloc] init] and not give it a second thought.<br />

You may wonder under what conditions init may return a different object from the<br />

one you allocated via alloc. For most classes this will never occur, but in special circumstances<br />

(implementing singletons, caches, or named instances, and so on), a class developer<br />

may decide to more tightly control when objects are created, preferring to return<br />

an existing object that’s equivalent rather than initialize a new one, for example.<br />

FAILURE IS A FACT OF LIFE<br />

It isn’t always possible for an initialization method to perform its intended task. For<br />

example, an initWithURL: method may initialize an object with data fetched from a<br />

website. If the URL provided is invalid or the iPhone is in flight mode, initWithURL:<br />

may not be able to complete its task. In such cases it’s common for the init method<br />

to free the memory associated with the new object and return nil, indicating that the<br />

requested object couldn’t be initialized.<br />

If there’s a chance that your initialization method may fail, you may like to explicitly<br />

check for this condition, as demonstrated here:<br />

CTRentalProperty newRental = [[CTRentalProperty alloc] init];<br />

if (newRental == nil)<br />

NSLog(@"Failed to create new rental property");<br />

Perhaps you’ve picked up on the fact that initialization methods aren’t always called<br />

init and that they can accept additional parameters. This is quite common, if not the<br />

norm, so let’s take a look at the why and how behind this.<br />

5.5.2 init is pretty dumb<br />

An initialization method that accepts no parameters has limited practical use. You<br />

often need to provide additional details to the initialization method in order for it to

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

Saved successfully!

Ooh no, something went wrong!