1、NSObject 有哪几种常用的初始化方式?
1> [[NSObject alloc]init]
这个肯定是我们经常看到的也是我们最初做iOS开发时使用的初始化方式,但是我们进一步去跟一下objc的源码,我们去看看到底做了什么?
- objc_alloc(Class cls) 并没有直接走[NSObject alloc], **后面会写一篇文章说明系统是如何把这个imp换掉的 **
- callAlloc(cls, true/checkNil/, false/allocWithZone/);这个方法是[NSObject alloc] 和objc_alloc(Class cls)的共用入口,只不过传的标志位不一样
- [NSObject alloc] 这个时候才真正调起 alloc 方法
- _objc_rootAlloc(Class cls)
- callAlloc(cls, false/checkNil/, true/allocWithZone/);
- id obj = class_createInstance(cls, 0); return obj //这里才被真正创建
-
- (id)init { return (id)self; }//init 啥也没干只是把Obj 自身返回了
2> [NSObject new]
这个肯定是我们经常看到的也是我们最初做iOS开发时使用的初始化方式,是发现有种更方便的初始化方式,我们同样来看看有什么区别?
-
- (id)new { return [callAlloc(self, false/checkNil/) init]; }//直接走了[[NSObject alloc]init]的路子
2、id obj = class_createInstance(cls, 0); 这个过程到底做了啥
- _class_createInstanceFromZone(cls, extraBytes, nil)//下层调用
- size_t size = cls->instanceSize(extraBytes); //为内存申请计算,下层做了一些字节对齐和限制,返回的是经过8字节对齐,至少是16字节的大小。
- obj = (id)calloc(1, size); 开始进入malloc 源码进行主线流程分析,可能有些细节判断(这里就不做了解)
- malloc_zone_calloc(default_zone, num_items, size);
- default_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size)
- nano_calloc(nanozone_t *nanozone, size_t num_items, size_t size)
- void *p = _nano_malloc_check_clear(nanozone, total_bytes, 1);
- segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey)//字节对齐,16字节对齐(对象)然后, return *p.到这里对象的内存已经开辟完成。
- obj->initIsa(cls);//初始化ISA
- initIsa(cls, false, false); ->objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)
- objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)
- isa.cls = cls; 给isa.cls 赋值,完成对象类的绑定。到这里对象的初始化完成。