Objective-C Lesson 11: Object Initialization


By this point we’ve covered the basics of the Objective-C language itself. With this knowledge and a willingness to learn, everything else can be picked up from Apple’s developer portal and the documentation. However, there are still topics which are used consistently through the language and are certainly worth talking about. This week’s topic is the creation of objects in your code—proper practices and syntax.

Allocation

Creating a new object in Objective-C is usually a two-step process. First, memory has to be allocated for the object, then the object is initialized with proper values.

The first step is accomplished through the alloc class method, inherited from NSObject and rarely, if ever, overridden. This method literally allocates a chunk of memory sufficient to hold your object (all of its instance variables). It then sets all of these values to zero or nil—this is so that you won’t get garbage values left behind by whatever had last used that chunk of memory. This means that all objects start out as nil, BOOLs start as NO, ints as 0 and floats are set to 0.0. These values are guaranteed after the alloc method is called.

Fraction *frac = [Fraction alloc];
// numerator and denominator are both 0

However, that object is not quite ready to use yet—it has to be initialized first (otherwise strange bugs are mostly guaranteed). This is accomplished by the init instance method, which is often overridden. These methods return an object of type id—the same object that is being initialized.

Fraction *frac = [[Fraction alloc] init];

It is important that you nest the alloc and init methods—there are instances where the initialization method may not return the same object as was allocated. This is true when working with classes such as NSString, which are in fact a public interface for a variety of classes. In these cases, the initialization method may choose to return an object that is not quite the originally requested class (for example, NSString‘s initialization methods might return a subclass of NSCFString.)

An initialization method for our Fraction class might look like this:

- (id)init {
	if (!(self = [super init]))	// Location 1
		return nil;		// Location 2
	// Initialize fraction to 3/5	// Location 3
	numerator = 3;
	denominator = 5;
}

Let’s look at this code. At Location 1, we have…well, a source of controversy, actually. In general, the recommended practice is to do it as shown, for a detailed breakdown of the issue, check out this link. Basically, this line states that if there is an issue with super’s init method and it returns nil, then your init method should also stop and return nil. Note that when a method hits a return statement, the method ends, even if there’s code left. This is why an else… block is not necessary. Why might [super init] not work? One case is if the object was being initialized with data from the internet. If there isn’t an internet connection, or if the internet resource can’t be found, [super init] might return nil, rather than some made-up or garbage data. At Location 2, we return nil, if necessary.

The method then assigns initial values to the instance variables at Location 3. In general, they should be set to reasonable, “empty” values if possible. Many programmers would (redundantly) set these values to zero, just to make their intentions clear. Here is a design decision you have to make. Assume you have a large class that has a lot of instance variables—a Car, for example. In the init method, you can choose to set default values for everything, if the intended use is to create a basic Car and use it. However, if the user is expected to extensively customize the Car, you might want to simply leave containers for the values, and not set default values.

Convenience Initializer

Most classes also have convenience initializers, which take arguments with which to set the ivars.

-(id)initWithNumerator:(NSInteger)num overDenominator:(NSInteger)denom {
	if (!(self = [super init]))
		return nil;
	numerator = num;
	denominator = denom;
}

The code is quite self-explanatory. The method assigns the values in the arguments to the class’s instance variables.

In the case of multiple initializers, it is advised that one of them be the designated initializer—generally it is the most complex initializer. This topic will be covered in next week’s Extension.

Constructors

Languages such as Java have a concept of constructors, which are language-level constructs that are automatically invoked through the new keyword. They combine the process of allocation and initialization, although most of the custom code is for the latter. They also have syntax restrictions—the method must not return anything (that’- how it becomes a constructor), it must have the same name as the class, any call to super must be the first statement… Objective-C has none of these restrictions. As stated above, initializers are not part of the language itself—there is no keyword to invoke them. As such, they are simply regular methods, which usually end up calling NSObject’s init method. In Java, calling the superclass’s implementation must be the first line, to ensure that you’re not dealing with garbage data. There is no such restriction in Objective-C—but any issues with garbage data are the responsibility of the programmer, not the compiler. This is one of C’s design goals—give responsibility to the programmer. But with great power comes great responsibility!

About these ads
Leave a comment

4 Comments

  1. What is the value of foo in the below code:
    NSNumber *foo;
    #at this point what reference does foo hold?
    foo=[[NSNumber alloc];
    #at this point is foo set to nil?
    foo=[[NSNumber init];
    #after this what does foo point to?Is it still nil?

    Reply
    • At your first location, you simply get a pointer to (null).

      At your second location, you get a pointer to a block of allocated memory (hence, ‘alloc’) with values zeroed out. Theoretically you have a working object. However, many important class variables have not yet been initialized. As a matter of fact, if you try to print the results of an ‘alloc’, you’d get an exception: -objCType only defined for abstract class. Therefore, you need to call init on the returned instance from alloc to set important variables.

      foo stops pointing to nil when it gets assigned to whatever alloc returns.

      Note that alloc is a class method, while init is an instance method. You can’t call [NSNumber init], you have to call it on the instance of NSNumber that [NSNumber alloc] returns.

      Finally, take a look at this article, which covers the design pattern behind alloc/init:
      http://www.informit.com/articles/article.aspx?p=1398610

      Reply
  1. Learn Objective-C in 24 Days « Programming for iOS
  2. Extension 13: Complex Initializers « Programming for iOS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

  • Welcome

    My goal is to make CupsOfCocoa into a beautiful source for beginners to the iPhone platform to get started. Subscribe below for more, and stay tuned!

  • Contact Me

    If you need to contact me for any reason, feel free to send me an email.
  • The Giving Spirit

    If you've found this site helpful, would you consider donating a little sum? Any amount is appreciated...Thanks so much!

  • Roadmap

  • Enter your email address to follow this blog and receive notifications of new posts by email.

    Join 225 other followers

  • Back to the Past

    April 2011
    S M T W T F S
    « Mar   May »
     12
    3456789
    10111213141516
    17181920212223
    24252627282930
  • Time Machine

  • You count!

    • 592,229 views
  • Worldwide Stats

    free counters
Follow

Get every new post delivered to your Inbox.

Join 225 other followers

%d bloggers like this: