Can someone help me understanding as why do we call an initialization method on super
first before initializing. I came across a piece of code in a subclass of UIView and wanted to know that here myMethod is always getting called that means I am not getting the frame set in UIView
, then why are we doing this and using an if
condition.
self = [super initWithFrame:CGRectMake(0, 0, 20, 100)];
if(self != nil) {
[self myMethod:data];
self.backgroundColor = [UIColor clearColor];
}
return self;
Let's say I have a UIView
subclass called SpinningView
. The code to create spinningView
would look like this:
SpinningView *spinner = [[SpinningView alloc] initWithFrame:CGRectMake(0.0, 0.0, 20.0, 20.0)]
Now let's take a look at the implementation of SpinningView's -initWithFrame:
method
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.backgroundColor = [UIColor clearColor];
}
return self;
}
The first line is simple assignment. We're assigning ourselves to the result of UIView
's implementation of -initWithFrame:
We use the if statement to see if self is even valid. If it's not we just return it. If it is, we configure it.
This is simply calling the constructor of the super class (in this case UIView).
You need to call UIView's constructor to make sure that all the variables you don't see from your subclass is set up properly, and that's what you do with [super init]
(or in this case initWithFrame:).
There are a few other reasons why it looks like this.
First of all [super init]
might return nil. Perhaps something went wrong initializing things in the code of the superclass. The check for self != nil
makes sure you don't use the object when something is already wrong with the object. It might even have been released by the super constructor.
In other cases the super constructor might actually return a different object altogether. Examples of this happening is with class clusters or when you implement a singleton.
To summarize:
- Always call the designated constructor (i.e. init-method).
- Always use the standard construct of
if ((self = [super init])) { /* own init */ } return self;
- Sometimes it looks different, but only for special reasons. If in doubt, always use (2).
Apple's documentation has a lot more info on this is you're interested.
Also, when overriding constructors like this, remember that there might be more than one constructor. For instance, if you add the view using Interface Builder, that view will be initialized using "initWithCoder:" instead. All constructors begin with "init" though.