The recommended init method in Objective-C is as follows:

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

Everybody writes this, everybody knows how to write this, so let me ask you a few questions:

  1. What does [super init] actually do?
  2. Why assign **[super init]** to self?
  3. What is the nature of super as a message recipient

Question 1:

At the code level,[super init] calls the parent class’s initialization method, that’s it. What does the parent class’s initialization method do? First of all, we know that the concept of object inheritance, a subclass inherited from the parent class, and then to realize all functions of the parent, this is what is – a relationship, such as a dog is a mammal, the dog must have the feature of mammals and the function, so in the initialization method of the subclass, you must first call of the parent class initialization method, in order to realize the initialization of the parent class related resources. [super init] [super init] [super init] [super init] [super init] [super init] [super init

Before we get to the second question, let’s see what happens when [super init] is executed

The first: [super init] initialization succeeds, which is a common normal case

The second: [super Init] fails to initialize, and we all know that oc creates an object in two steps,alloc opens up memory,init initializes the object, but init also does another thing, and if initialization fails,init method returns nil, so look at the top code, if self is nil, then inside if(self) Will not be executed, ensuring the robustness of the program

Self = [super init], memory points to an unrelated address

There’s no doubt about the first or the second result, but let’s look at the third one, a lot of people are confused, don’t understand what it means, look at the code below, okay

Suppose we have a Father class and a Son class

Init for Father:

- (instancetype)init
{
    id tmp = self;
    self = [Father alloc];
    [tmp release];
    return  self;
}
Copy the code

Son’s init method is as follows:

- (instancetype)init
{
    if (self = [super init]) {

        NSLog(@"son init %@", self.class);

    }
    return  self;
}
Copy the code

At this point the compilation passes, but a runtime error occurs when an instance of Son uses Son’s extended properties. The reason for the error is that the init method for Father uses [Father alloc] to retrieve a space suitable only for storing the Father instance. Son’s init method assumes that this is a block of space suitable for Son, and attempts to read or write Son’s extended properties generate a runtime error

Therefore, when the init method needs to realloc a space, the correct way to write it is as follows:

- (id) init
{
    id tmp = self;         
    self = [[self class] alloc];          
    [tmp release];
    //other staffs
    return self;
}
Copy the code

Note in line 4 that [self class] gets the class instance of the instance to which self points, in this case Son. So any subclass of Father’s init method is safe.

Using the example above, we can answer question 2, which simply prevents the parent initializer from releasing the space referred to by self and realloc a space, so that [super] If (self = [super init]). This is a common recommendation, assigning and testing nil in case the superclass changes during initialization and returns a different object

Problem 3 is simple: super is not really a pointer, and the essence of [super message] is that self receives the message of the parent class. Note that in [super message], the message method appears as self in the context of [super Message], i.e., the subclass instance.