Original source: Martin_wjl (@Martin_wjl) reprinted from Bole Online
There are two ways to initialize an object: [class new]
[[class alloc] init]
For the latter, there is the process of allocating and initializing, alloc
allocating enough memory for the object from the application's virtual address space, and adding a reference count of the new object to 1, initializing the object's member variable to zero, and init
doing a real initial work, giving the object's instance variable a reasonably useful value.
Generally not recommended [class new]
, and recommended to use [[class alloc] new]
, see the Source analysis:
<textarea class="crayon-plain print-no" style="-moz-tab-size: 4; font-size: 13px ! important; line-height: 15px ! important; z-index: 0; opacity: 0; height: 293px;" readonly="" data-settings="dblclick">+ new {id newObject = (*_alloc) ((Class) self, 0); Class Metaclass = self->isa; if (class_getversion (Metaclass) > 1) return [NewObject init]; else return newObject; }//And alloc/init like this: + alloc {return (*_zonealloc) ((Class) self, 0, malloc_default_zone ()); }-init {return self;}</textarea>
12345678910111213141516171819 |
+ new { id newObject = ( *_alloc) ( (class) self, 0) ; Class metaclass = self , ISA; if (class_getversion(metaclass) > 1) return [newObject init]; Else return newObject; }//And alloc/init like this:+ alloc { return (*_zonealloc)((Class)self, 0, malloc_default_zone()); }- init { return self ; } |
When [class new]
we find the default calling [newObject init]
method, we cannot use the custom initialization method, which has more limitations. Then it [class alloc] init]
will be more convenient, of course, [class alloc] init]
the design is due to historical reasons.
Why do you write that? <textarea class="crayon-plain print-no" style="-moz-tab-size: 4; font-size: 13px ! important; line-height: 15px ! important; z-index: 0; opacity: 0;" readonly="" data-settings="dblclick">-(Instancetype) init{if (self = [super init]) {//Custom initialization} return to self;}</textarea>
1234567 |
- (instancetype)init { if (self = [super init]) { //Custom initialization } return self ; } |
We know that we are alloc
returning a valid uninitialized object instance. For self
alloc
pointers that are returned, they can be accessed within all method scopes.
But for super
that, it's just a "compiler indicator," which tells the compiler to search for the implementation of the method in the parent class.
Priority calls [super init]
are made to enable the superclass to do their own initialization work.
So what if (self = [super init])
do you do again?
Here is the fear of the parent class initialization failure, if the initialization of an object fails, it will return nil
, when returned when nil
the body of the test will self = [super init]
not continue to execute. If you do not, you may be manipulating an unusable object whose behavior is unpredictable and may eventually cause your program to crash.
Understanding Self & Super
See a classic online topic:
<textarea class="crayon-plain print-no" style="-moz-tab-size: 4; font-size: 13px ! important; line-height: 15px ! important; z-index: 0; opacity: 0;" readonly="" data-settings="dblclick">@implementation son:father-(id) init{self = [super init]; if (self) {NSLog (@ '%@ ', Nsstringfromclass ([Self class])); NSLog (@ "%@", Nsstringfromclass ([Super class])); } return self;} @end</textarea>
123456789101112 |
@Implementation Son : Father - (ID)init {Self = [super init]; if (self) { NSLog (@ "%@" , nsstringfromclass ([ Self class]) NSLog(@"%@", nsstringfromclass([Super class]) c15>); } return self ; }@End |
self
Represents the object of the current class, and super
is a compiler identifier, and points to the self
same message receiver. In this case, either or both [self class]
, the [super class]
recipient of the message is an object, but unlike the method that is called when it is invoked, the method is found in the Son
child class, and when the super
self
self
class
Son
super
methods are called, the class
parent class Father
Find methods in the.
When a method is called, it is [self class]
converted to a objc_msgSend
function, which is defined as follows:
<textarea class="crayon-plain print-no" style="-moz-tab-size: 4; font-size: 13px ! important; line-height: 15px ! important; z-index: 0; opacity: 0;" readonly="" data-settings="dblclick">ID objc_msgsend (ID self, SEL op, ...)</textarea>
1 |
ID objc_msgsend(ID self, SEL op, .. . ) |
This is the time to start the message delivery and forwarding process, the first Cache
way to find the method, and then the current class, if still find not to go to the parent class, until the NSObject
class
For NSObject
classes, - (Class)class
the implementation is as follows:
<textarea class= "Crayon-plain print-no" style= "-moz-tab-size:4"; Font-size:13px! Important line-height:15px! Important z-index:0; opacity:0, "readonly data-settings=" DblClick ">-(Class) class {return object_getclass (self); }</textarea>
123 |
- (class)class { return object_getclass(self); } |
So the print result isSon
When the method is called, it is [super class]
converted to objc_msgSendSuper
, the function is defined as follows:
<textarea class="crayon-plain print-no" style="-moz-tab-size: 4; font-size: 13px ! important; line-height: 15px ! important; z-index: 0; opacity: 0;" readonly="" data-settings="dblclick">ID objc_msgsendsuper (struct objc_super *super, SEL op, ...)</textarea>
1 |
ID objc_msgsendsuper(struct objc_super *Super, SEL op, .. . ) |
objc_msgSendSuper
The data type of the first parameter of a function super
is a pointer objc_super
to the struct body
<textarea class= "Crayon-plain print-no" style= "-moz-tab-size:4"; Font-size:13px! Important line-height:15px! Important z-index:0; opacity:0; "ReadOnly data-settings=" DblClick ">struct objc_super {__unsafe_unretained ID receiver; __unsafe_unretained Class Super_class;}; </textarea>
1234 |
struct objc_super { __unsafe_unretained ID Receiver ; __unsafe_unretained Class super_class; }; |
The struct contains two members, the first of which receiver
represents an instance of a class. The second member is the record of what the parent class of the current class is, the first thing Father
to look for in this class - (Class)class
, and then the process of message passing.
You will find that both the self
and the super
message recipients are the same, and the message is delivered, and the method that eventually processes the message is the NSObject
- (Class)class
method in.
Reference article:
- Objective-c Runtime
- In-depth understanding of Objective-c's runtime mechanism
- What exactly are super in objective-c?
Probing: thinking about self = [Super init]