前言
大家好,我是milo,当我们在使用 [[xx类 alloc] init] 创建对象的时候,是否知道其内部机制呢?本篇文章就是来揭开alloc、init的神秘面纱的。
alloc和init
以下面这个简单的person类(继承NSObject)初始化对象来探讨探讨
Person *p = [Person new]; // 和[[Person alloc] init]作用相同
由于Person类继承NSObject,而NSObject声明了alloc和init方法,所以Person类也默认继承了alloc和init方法,所以Person类就可以直接调用方法。
需要注意的是:
alloc是NSObject的类方法,它用于分配存储空间,同时返回一个instancetype(关联返回类型),就相当于
Person *p1 = [Person alloc];
通过alloc分配内存以后,就需要调用init方法进行初始化,init方法是对象方法,在这一步中会默认对成员变量进行赋值为0的操作,同时返回instancetype(关联返回类型),就相当于
Person *p2 = [p1 init];
因为alloc和init方法都是返回instancetype(关联返回类型),所以可以用本类的对象指针指向它们。而为了简便,才变成了下面那样简便的写法。
Person *p2 = [[Person alloc] init];
完整地创建一个可用的对象需两步:
1.分配存储空间 +alloc
2.初始化 -init
重写构造方法
当我们想让对象init以后,person默认的一个成员变量 _age = 10,应该怎么做?
答:重写init方法。
我们知道init方法是类继承NSObject而来的,所以我们就可以通过重写init方法,完成自定义初始化。重写init方法十分简单,在.m文件里像下面代码一样重写就可以了。
#import "Person.h"
@implementation Person
- (id)init
{
if ( self = [super init] )// 如果对象初始化成功,才有必要进行接下来的初始化
{ // 初始化成功
_age = 10;
}
// 返回一个已经初始化完毕的对象
return self;
}
@end
需要注意的是:
[super init]的作用是先去父类的init方法。Person的父类是NSOject,NSObject有一个isa指针指向当前类,这个isa指针的作用很大(没有它就不能干活),所以,我们必须要先初始化父类的init方法保证isa可用。
if( self = [super init] )这是一种通常的建议写法,赋值并测零只是为了防止超类在初始化过程中发生改变,返回了不同的对象。
初始化的时候是从父类初始化开始的,“没有爸爸哪来儿子?”
重写构造方法过后对象初始化就会默认_age = 10了,就达到了目的了。
自定义构造方法
重写构造方法做到的只是无参数初始化属性,当我们需要传参赋值,类似如下方式初始化属性的时候,就需要自定义构造方法了。
Person *p = [[Person alloc] initWithAge:10];
每一个对象都可以根据不同的参数,初始化不同的值,比较灵活。
而我们要做的只是重新声明一个initWithAge:方法,实现如下即可:
- (id)initWithAge:(int)age
{
if ( self = [super init] )
{
_age = age;
}
return self;
}
和上面重写构造方法几乎一模一样对吧!因为就是用这个方法取代init方法的,所以要完成的步骤也几乎一样。
网友评论