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:
- What does [super init] actually do?
- Why assign **[super init]** to self?
- 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.