1.分配对象
类对象和实例对象的关系
类定义完成后,编译器在内存种自动生成唯一的类对象,实例对象都是通过调用类对象的类方法生成;
类对象是工厂,同时也是 蓝图,实例对象是产品。
方法:
分配(alloc)从操作系统获得一块内存并将其指定为存放对象的实例变量的位置。
初始化(init)按照类(模板)创建一个实例(对象)
Car *car = [Car alloc]; 错误:仅分配对象,未初始化。
Car *car = [Car alloc];
[Car init];
错误
Car *car =[ [Car alloc]init]; 正确
id anObject = [ [SomeClass alloc]init];
if(anObject)
[anObject someOtherMessages];
else
...
又动态内存分配的时候就要有判断。
初始化函数编写原则:
编写初始化(init)方法时,须确定在该方法种希望完成什么工作
1.方法不需要参数,初始化方法名用init足已。
若需要参数则以init未前缀标签。
2.初始化方法的返回类型应该id。
因为要改写init 的子类并不确定,所以要用泛型指针。
初始化函数编写风格:
风格1:
init方法种不创建任何对象,只为engine和tire对象预留位置。
创建Car类的代码将必须创建engine和tire对象,并使用访问方法为其赋值。
适用于需要init方法种创建复杂但实际可能用不上的对象时。
第四章实例代码,不使用重载的时候。
风格2:
调用 init 方法创建engine 对象和全部tire 对象。
对Car类进行分配、初始化后立即出现一个完整的对象(汽车)。
重载后的代码风格。
便利化初始化函数
对象种多个init开头的方法;
是遵循命名约定的普通方法
可完成某些额外的工作的初始化方法
与alloc配对使用,需要release
不是init开头的就不需要和alloc一起使用
init
在对象生成的时候发生作用
set
在对象生成以后发生作用
注意初始化函数设计的三种情形:
1.从继承,本身新增数据成员,且数量较少。
2.从继承,本身新增数据成员,且数量较多。
3.从继承,本身新增数据成员,然后该类被其他类继承,且仍然新增数据成员。
解决:
case1:采用前述准则,对所有数据成员进行组合构造便利初始化函数
case2:仅重载init 对常用数据成员构造便利初始化函数。
case3:子类化问题。
指定初始化函数的实现方式
1.超类种的初始化函数 应按照参数最多的初始化函数的方式实现。
总结:
超类的非初始化函数调用自身的初始化函数。
原初始化函数无入参部分,使用固定值。
原初始化函数有入参部分,使用可变值。
2.子类种的初始化函数首先调用超类初始化函数(此时将调用指定初始化函数),并为新增成员变量初始化。
总结:
调用超类的指定初始化函数
为新增成员初始化
必须将超类的初始化函数返回值赋给self对象
初始化函数规则
1.不为自己创建的类创建初始化函数
不需要设置任何状态,或只需要alloc方法将内存清0,直接调用超类的init函数
2.若构件了一个初始化函数
一定要在自己的指定初始化函数种调用超类的指定初始化函数。
3.若初始化函数不止一个:
选择一个作为指定初始化函数;
被选定的方法应调用超类的指定初始化方法;
按照指定初始化函数的形式实现其他初始化函数。