-1

Possible Duplicate:
In Objective-C why should I check if self = [super init] is not nil?

I'm new at Ob-C, and am having a hard time understanding why the value returned is non-nil as tested by the "if statement".

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

This method invokes the parent initializer first. Executing the parent's initializer ensures that any inherited instance variables are properly initialized. You must assign the result of executing the parent's init method back to self because an initializer has the right to change the location of the object in memory (meaning its reference will change). If the parent's initialization succeeds, the value returned will be non-nil, as tested by the if statement. As the comment indicates, inside the block that follows is where you can put your own custom initialization code for your object. This will often involve allocating and initializing instance variables that are in your class.

Pasted code and text from From Stephen Kochan "Programming in Objective-C, Fourth Edition"

Community
  • 1
  • 1
  • I'll be honest...I never even thought about that. However calling 'super init' calls the init method of the superclass (NSObject) for example. In there, it determines the location of the allocated memory and does some preliminary initializations. I am guessing that it needs to return 'self', because we can 'pass' the parameter in a chain like that. But I'm definitely not sure. – ATaylor Nov 01 '12 at 00:17
  • are you asking why [super init] returns non-nil, or are you asking why we bother checking if the value returned is non-nil? – yfrancis Nov 01 '12 at 00:19
  • Off: @yfrancis hi there! –  Nov 01 '12 at 00:29
  • @yfrancis I'm asking why it returns non-nil. – Brad Littlefield Nov 01 '12 at 01:05
  • well let's consider the alternative, if init returns nil, then you don't have a pointer to an object, which means you'd have to perform memory allocation yourself, defeating the purpose of `+alloc` entirely. – yfrancis Nov 01 '12 at 01:09
  • @yfrancis Thanks. Now it's clear I think. As I understand it, the override allow the class to perform something special outside of the parent init? Since the class has one or more pointers to objects, then init must return some value. Essentially it's hiding an id instance from any user which could be called by the class from anywhere in the module? Correct? As I said, i'm new to these concepts and appreciate the help from those that know much much more than me. – Brad Littlefield Nov 01 '12 at 04:11
  • I provided a more detailed explanation in my answer – yfrancis Nov 01 '12 at 04:48

1 Answers1

2

Consider the following scenario, you have a parent class, which we'll call Parent, that has the following layout:

@implementation Parent {
    int value;
}

and you have a class Child, which is a subclass of Parent, and has the following layout:

@implementation Child {
    int other;
}

within the Child subclass, you have no direct access to the Parent ivar called value. However, in its initialization, Parent assigns some integer to value, and some functionality in Parent depends on this value being set.

if Child does not call [super init], value will never be initialized and part of the functionality of Parent, which Child inherits, will be broken. The init method is defined to return a pointer to the initialized object instance. If you ignore the return value of [super init], you can get into trouble, because the parent init may have decided to reassign the object instance to some location other than the one provided by the allocator.

For instance, NSString can detect initialization with empty string literals, and will return a pointer to a constant NSString reference instead of one on the heap. So say you just call [super init] and ignore its return value, and keep using the self pointer value passed to the Childs init method, you're suddenly using a dangling pointer!

This is an extreme case, but the point is, if you intent to inherit functionality from your parent class, you should assign self to [super init], and you should check if it returns nil because it may have decided to fail initialization and destroy the memory provided to it by the allocator.

Community
  • 1
  • 1
yfrancis
  • 2,616
  • 1
  • 17
  • 26