1.15. Allocating and Initializing Objects

Problem

You want to create an instance of a new object, but you don’t understand the difference between allocation and initialization and why you should have to both allocate and initialize an object before you can use it.

Solution

You must both allocate and initialize an object before using it. An object can be allocated using the alloc instance method. This class method will allocate memory to hold the object and its instance variables and methods. However, allocation leaves memory undefined. So in addition, each object must be initialized, which sets the values of its data. One initialization method must be the designated initializer, which is normally the initialization method with the most parameters. For instance, the initWithFrame: method is the designated initializer of objects of type UIView. Always allocate and initialize your objects, in that order, before using them.

When implementing a new object, do not override the alloc method. This method is declared in NSObject. Instead, override the init method and create custom initialization methods that handle required parameters for the specific object you are working on.

Discussion

An object that inherits from NSObject must be prepared for use in two steps:

Allocation

The allocation is done by invoking the alloc method, which is implemented in the NSObject class. This method creates the internal structure of a new object and sets all instance variables’ values to zero. After this step is done, the init method takes care of setting up the default values of variables and performing other tasks, such as instantiating other internal objects.

Initialization

Initialization is the process by which a class prepares each of its instances’ storage (variables), required internal data structure and whatnot. Think of allocation as getting inside a car and initialization as switching on the ignition.

Let’s look at an example. We are creating a class named MyObject. Here is the .h file:

#import <Foundation/Foundation.h>

@interface MyObject : NSObject

- (void) doSomething;

@end

The implementation of this class is as follows (the .m file):

#import "MyObject.h"

@implementation MyObject

- (void) doSomething{

  /* Perform a task here */
  NSLog(@"%s", __FUNCTION__);

}

@end

The doSomething instance method of the MyObject object will attempt to print the name of the current function to the console window. Now let’s go ahead and invoke this method by instantiating an object of type MyObject:

MyObject *someObject = [[MyObject alloc] init];
/* Do something with the object, call some methods, etc. */
[someObject doSomething];

This code will work absolutely fine. Now try to skip initializing your object:

MyObject *someObject = [MyObject alloc];
/* Do something with the object, call some methods, etc. */
[someObject doSomething];

If you run this code now, you will realize that it works absolutely fine, too. So, what has happened here? We thought we had to initialize the object before we could use it. Perhaps Apple can explain this behavior better:

An object isn’t ready to be used until it has been initialized. The init method defined in the NSObject class does no initialization; it simply returns self.

Simply put, this means the init method is a placeholder for tasks that some classes need to perform before they are used, such as setting up extra data structures or opening files. NSObject itself—along with many of the classes you will use—does not have to initialize anything in particular. However, it is a good programming practice to always run the init method of an object after allocating it in case the parent of your class has overridden this method to provide a custom initialization. Please bear in mind that the return value for initializer methods of an object is of type id, so the initializer method might even return an object that is not the same object that the alloc method returned to you. This technique is called two-stage creation and is extremely handy. However, discussing this technique is outside the scope of this book. For more information about two-stage creation, please refer to Cocoa Design Patterns by Erik M. Buck and Donald A. Yacktman (Addison-Wesley Professional).

Get iOS 5 Programming Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.