对象的alloc+init
专业领域包括做网站、成都网站建设、成都商城网站开发、微信营销、系统平台开发, 与其他网站设计及系统开发公司不同,成都创新互联公司的整合解决方案结合了帮做网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,为客户提供全网互联网整合方案。
类对象的new方法可以创建一个属性均为0的对象
new方法实际上是两个方法的连续调用:
1)分配存储空间 alloc 类对象方法
2)初始化 init 对象方法
也就是说 Person *p = [Person new]; 等同于: Person *p = [[Person alloc] init];
alloc和init方法都是NSObject的方法,故所有的OC类型都可以使用这种方式创建对象
init方法:
- (instancetype)init
该方法的默认操作:调用父类的init方法,并返回对象本身,成员变量的初值为0
重写init方法
默认的init方法,将对象的属性初值设为0,如果我们想要指定一个初值,就需要重写该方法。
NSObject的子类重写init方法的步骤:
1. 调用父类的init方法,将其父类中的属性初始化
2. 为子类的属性初始化
3. 返回对象本身
重写init方法一般形式:
如:Person类,包含一个属性_age
- (instancetype) init { if ( self = [super init] ) { _age = 10; } return self; }
再如:Person的子类Student,包含一个属性score
- (instancetype) init { if ( self = [super init] ) {//调用了父类Person的init函数 _score = 1; } return self }
init方法是一层一层往下调用的
重写构造方法的目的是为了对象创建出来,成员变量就会有一些规定的值
自定义init方法
默认的Init方法不带参数,只能为对象初始化一些固定值
通过自定义init方法可以实现通过参数初始化对象属性。
返回值一般是instancetype类型
方法名以initWith开头
如Person类中包含属性name和age
- (instancetype) initWithName:(NSString *) name { if ( self = [super init] ) { _name = name; } return self; } - (instancetype) initWithName:(NSString*)name age:(int) age { if ( self = [super init] ) { _name = name; _age = age; } }
子类的init方法应指定调用父类的哪个init方法
如Person子类Student类:
- (instancetype) initWithName:(NSString *)name age:(int) age score:(int) score { if ( self = [super initWithName:name age:age] ) { //也可以用super的init方法及set方法,但不推荐 _score = score; } return self; }
有时我们需要创建一个现有对象的副本,则应编写一个拷贝构造方法,参数为对象指针
- (instancetype) initWithPerson:(Person*) p { if ( self = [super init] ) { _age = p.age; _name = p.name; } return self; }
一个对象销毁时,会调用一个dealloc方法
- (void)dealloc
该方法在最后应调用父类的dealloc方法
dealloc方法不能直接调用
需要注意的是,在引入ARC机制后,重写这个方法时不能调用父类被重写的dealloc方法
类对象
我们定义的类也是一种对象 ,是Class类的对象
Class创建Person类对象,再通过Person类对象方法来创建对象。
这里:类对象 == 类
之前说过,每个对象都一个isa指针,isa指针指向就是类对象
方法的调用过程:
实际上就是通过基类部分的isa属性,找到成员函数列表,再将消息传递的参数拿过来和函数列表中的参数对比。 在自己的函数列表中找不到就到父类的函数列表中去找,直到找到为止。
类方法
通过对象调用的方法,称为对象方法,如init description等。
通过类对象调用的方法,称为类方法,如alloc new等。
+ (instancetype)alloc + (instancetype)new
对象方法在声明和定义时,以-开头
类方法在声明和定义时,以+开头
在类方法中,self表示类对象,super表示父类对象
类方法在子类中也可以被重写 ,类方法和对象方法可以重名
访问类对象:
任意对象都可以通过class方法,获得其类对象
- (Class)class
也可以通过类的class类方法,获得其类对象
+ (Class)class
如:(c1和c2是同一类对象)
Person *p1 = [Person new]; Person *p2 = [Person new]; Class c1 = [p1 class]; Class c2 = [p2 class]; Person *p3 = [c1 new];
类对象的加载
在程序运行开始时,会加载一次项目中所有的类,类加载完毕就会调用类的load方法。
程序在第一次使用这个类时,会调用类的initialize方法。
这两个方法是可以重写的,都是类对象方法
+ (void)load + (void)initialize
注意:
使用第一次使用该类时,会先调用该类的父类的initialize方法
当有分类时,类和分类的load方法都会被调用;第一次使用该类时,只会调用分类的initialize方法。
类方法封装对象的创建
当实例化一个对象时,需要编写类似下面的代码:
Person *p = [[Person alloc] initWithAge:20];
这样的代码比较啰嗦,可以添加一个类方法来简化:
+ (instancetype) personWithAge:(int) age { return [[Person alloc] initWithAge:age]; }
这样实例化对象的代码为:
Person *p = [Person personWithAge:20];