iOS new 和alloc/init 的区别

在开发中,创建一个对象我们有如下方式:

[objc]  view plain  copy
  1. NSObject *obj_1 = [[NSObject alloc]init];  
  2. NSObject *obj_2 = [NSObject new];  
new源码:
[objc]  view plain  copy
  1. + (id)new  
  2. {  
  3.     id newObject = (*_alloc)((Class)self0);  
  4.     Class metaClass = self->isa;  
  5.     if (class_getVersion(metaClass) > 1)  
  6.         return [newObject init];  
  7.     else  
  8.         return newObject;   
  9. }  
alloc/init源码:

[objc]  view plain  copy
  1. + (id)alloc  
  2. {  
  3.     return (*_zoneAlloc)((Class)self0, malloc_default_zone());  
  4. }  
  5.   
  6. - (id)init  
  7. {  
  8.     return self;  
  9. }  
可以看出,两种方式基本上一致。区别上从_alloc和_zoneAlloc中可以看出,new使用了zone,它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提升了程序处理速度。
但如果使用new的话,初始化方法被固定死只能调用init.不能再使用init开头的其它初始化方法,据说最初的设计是完全借鉴Smalltalk语法来的,传说那个时候已经有allocFromZone:这个方法,只是给对象分配了内存,并没有初始化实例变量,但是这个方法需要传个参数id myCompanion = [[TheClass allocFromZone:[self zone]] init];
这个方法像下面这样:
[objc]  view plain  copy
  1. + allocFromZone:(voidvoid *) z  
  2. {  
  3.     return (*_zoneAlloc)((Class)self0, z);  
  4. }  
  5.   
  6. //后来简化为下面这个:  
  7. + alloc  
  8. {  
  9.     return (*_zoneAlloc)((Class)self0, malloc_default_zone());  
  10. }  
并且allocFromZone:在苹果文档上已经说明,这个方法是因为历史原因所存留,它的参数zone可以直接无视,已经不再在object-c上使用,也不需要再重写这个方法。

官网的说法,alloc方法即使重写也不要写任何初始化的操作,它其实也调用了allocFromZone。


总的来说,两种方式创建对象现在基本上一样,区别就是使用new只能默认init进行初始化,alloc方式可以使用其它的init开头的方法进行初始化。

猜你喜欢

转载自blog.csdn.net/ssyyjj88/article/details/80102210