alloc
是在物理内存中分配了一块内存,并且返回一个指针。
MyClass* myObj = [MyClass alloc];
此时myObj
还不能使用,因为它的内存状态还没有得到正确的设置。init
设置对象的初始化状态并且将其返回。
注意:[a init]
的返回值并不一定是a自身 ,原因如下:
//init的源码
-init
{
self = [super init]; // 1.
if(self) // 2.
{
....
}
return self; // 3.
}
1. 首先,你需要调用超类的init
方法去设置超类的实例变量等,其返回值不不一定等于原来的self
,所以你需要将返回值重新赋值给self.
2. 如果self
非空,则表明被超类控制的部分已经得到正确的初始化。词时,所有的实例变量都设置为nil
(如果是对象),或者0(如果是整型)。接下来,你可以执行额外的初始化设置。
3. 返回self
测试:
NSString *name = [NSString alloc];
NSLog(@"%p",name);
name = [name init];
NSLog(@"%p",name);
//打印出的两个的内存地址不一样,因为执行了self=[super init],重新分配了空间
不过:
NSObject *obj = [NSObject alloc];
NSLog(@"%p",obj);
obj = [obj init];
NSLog(@"%p",obj);
//打印出的两个地址是一样的,为什么呢?
NSObject打印出来的两个地址一样,这是为什么呢?
因为NSObject是一切类的基类,当[[NSString alloc]init]执行时,调用的[super init]就是 NSObject中的init方法,既然NSObject身为基类,它也就无法调用super init,所以当NSObject执行[[NSObject alloc]init]时,也就没有了init重新分配空间这一环节。
回归正题,因为init
和alloc
的返回值不一定相等,所以不要将两个方法分开使用,如以下代码:
//不要这样写
MyClass* myObj = [MyClass alloc];
[myObj init];
也不建议使用以下写法:
//不要这样写
MyClass* myObj = [MyClass alloc];
myObj=[myObj init];
因为你很有可能忘记写myObj=
永远使用以下写法:
//要这样写
MyClass* myObj = [[MyClass alloc] init];
也不建议使用new
方法,因为
//new的源码
+ new {
id newObject = (*_alloc)((Class)self, 0);
Class metaClass = self->isa;
if (class_getVersion(metaClass) > 1)
return [newObject init];
else
return newObject;
}
如果使用new的话,初始化方法被固定死只能调用init
采用alloc的方式可以用其他定制的初始化方法
所以不建议使用new
方法创建对象
参考:
https://www.cnblogs.com/chars/p/5194067.html
https://www.jianshu.com/p/a4859a37f59b