开发者

Assignment of self on if condition-Objective C

self is a hidden instance variable that points to the current object:

- (id) initWithAmount:(double)theAmount forBudget:(Budget *)aBudget{

        if(self = [super init]){

                budget = aBudget;
                amount = theAmount;

        }
        return self;
}

is it similar to

this.budget=super.aBudget;
this.amount=super.theAmount;

Normally:

if(control)//true or false
     {
      //stmts will get executed 
     }

but instead of returning a true value here the self is assigned开发者_如何学Go with super. Why is it so?

Is it similar to constructor. How to use constructors(default,parameterised and copy) in objective C?


Because an assignment expression also returns the result of the assignment,

if (self = [super init]) { ...

is equivalent to:

self = [super init];
if (self) { ...

And since if does not just test pure boolean values but treats everything that is non-zero, non-NULL or non-nil as true, the if statement tests if self is nil after the assignment.

When we write our own init methods, we are supposed to assign [super init] to self because a init method is free to return a different object than the receiver of the method. If we just called [super init] without assigning it to self, we might initialize a different object than self, which is clearly not desirable.


This form is just the short form of the following code:

- (id)initWithAmount:(double)theAmount forBudget:(Budget *)aBudget {
  self = [super init]; // you must do this, because every object inherits all properties
                       // from the parent class, and they must be initialized

  // init can return nil if there was an error during the initialization
  // so if the parents initialization failed, there is no point of initializing
  // the child object
  if (self != nil) {
    budget = aBudget;
    amount = theAmount;
  }

  return self;
}


It's the way initializers are defined in Objective-C. It's part of the two-stage creation pattern: seperating memory allocation and initialization of the object. As self references the object instance where the initializer resides in it has to go up the inheritance tree and set what they return to itself, after that it's your turn.

The call of super is only used in the designated initializer. You could have more initializers which should always use the designated initializer.

The pattern

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

Is the correct way to handle failures. The test will fail if self = [super init]; returns nil: An error occured in initializers up the inheritance tree, so you don't want to use a failed initialization and skip your own code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜