SteveMDavis 0 Newbie Poster

Hi there!

I'm having trouble understanding the following in Stephen Kochan's book "Programming in Objective-C" - 4th Edition. I hope that you can help me understand it.

In Chapter 10 on the section on "Initialising Objects", Stephen writes:

"You should adhere to the following two strategies when writing initialisers.

It might be the case that you want to do something special whenever one of the objects in your class gets initialised. For example, that's the perfect place to create the objects that your class uses and references through one or more instance variables. A perfect example of that would be our Rectangle class; it would be reasonable to allocate the rectangle's XYPoint origin in the init method. To do so, we just have to override the inherited init method.

There's a standard 'template' that's used for overriding init, and it looks like this:

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

     return self;
}

This method invokes the parent initialiser first. Executing the parent's initialiser ensures that any inherited instance variables are properly initialised.

You must assign the result of executing the parent's init method back to self because an initialiser has the right to change the location of the object in memory (meaning its reference will change).

If the parent's initialiser 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 code for your object. This will often involve allocating and initialising instance variables that are in your class."

Ok so thus far I have understood what Stephen Kochan is trying to say but I'm completely mystified by the next part. I hope you can help.

"If you class contains more than one initialiser, one of them should be your designated initialiser and all the other initialisation methods should use it. Typically, that is your most complex initialisation method (usually, one that takes the most arguments)."

So, my first question is: why have all the other initialisation methods if they're all going to use one particular one in this case the "designated" initialiser?

Stephen Kochan goes on to say:

"Creating a designated initialiser centralises your main initialisation code in a single method. Anyone subclassing your class can then override your designated initialiser to ensure that new instances are properly initialised".

Could you give an example of this? I'm not quite sure I understood what he's saying.

Stephen continues:

"Based on that discussion, your initialisation method initWith:over: for your Fraction class might look like this:

- (Fraction *) initWith: (int) n over: (int) d
{
     self = [super init];

     if (self) {
          [self setTo: n over: d];

     return self;
}

Following the initialisation of super (and its success, as indicated by the return of a nonzero value) you use the setTo:over: method to set the numerator and denominator of your Fraction. As with other initialisation methods, you are expected to return the initialised object, which you do here.

Program 10.1 tests your new initWith:over: initialisation method.

#import "Fraction.h"

int main (int argc, char * argv[ ])
{
     @autoreleasepool {

     Fraction *a, *b;

     a = [[Fraction alloc] initWith: 1 over: 3];
     b = [[Fraction alloc] initWith: 3 over: 7];

     [a print];
     [b print];

     }
     return 0;
}

Output:

1/3
3/7"

So far I have understood the code. The following part I don't understand at all:

"To adhere to the rule stated earlier about a designated initialiser, you should also modify init in your Fraction class. That's particularly important if your class might be subclassed.

Here's what the init method could look like:

- (id) init
{
     return [self initWith: 0 over: 0];
}

"

Why is this important if we want to subclass?

Stephen Kochan continues:

"When your program begins execution, it sends the initialisation call method to all your classes. If you have a class and associated subclasses, the parent class gets the message first. This message is sent only once to each class, and it is guaranteed to be sent before any other messages are sent to the class. The purpose is for you to perform any class initialisation at that point. For example, you might want to initialise some static variables associated with that class at that time."

I didn't really understand this last part either. I hope that you can help. and if yes, then please do so at my email address. I'll appreciate your help a lot.

Steve