Objective-C(6)对象的构造
对象的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=[superinit]){_age=10;}returnself;}
再如:Person的子类Student,包含一个属性score
-(instancetype)init{if(self=[superinit]){//调用了父类Person的init函数_score=1;}returnself}
init方法是一层一层往下调用的
重写构造方法的目的是为了对象创建出来,成员变量就会有一些规定的值
自定义init方法
默认的Init方法不带参数,只能为对象初始化一些固定值
通过自定义init方法可以实现通过参数初始化对象属性。
返回值一般是instancetype类型
方法名以initWith开头
如Person类中包含属性name和age
-(instancetype)initWithName:(NSString*)name{if(self=[superinit]){_name=name;}returnself;}-(instancetype)initWithName:(NSString*)nameage:(int)age{if(self=[superinit]){_name=name;_age=age;}}
子类的init方法应指定调用父类的哪个init方法
如Person子类Student类:
-(instancetype)initWithName:(NSString*)nameage:(int)agescore:(int)score{if(self=[superinitWithName:nameage:age]){//也可以用super的init方法及set方法,但不推荐_score=score;}returnself;}
有时我们需要创建一个现有对象的副本,则应编写一个拷贝构造方法,参数为对象指针
-(instancetype)initWithPerson:(Person*)p{if(self=[superinit]){_age=p.age;_name=p.name;}returnself;}
一个对象销毁时,会调用一个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=[Personnew];Person*p2=[Personnew];Classc1=[p1class];Classc2=[p2class];Person*p3=[c1new];
类对象的加载
在程序运行开始时,会加载一次项目中所有的类,类加载完毕就会调用类的load方法。
程序在第一次使用这个类时,会调用类的initialize方法。
这两个方法是可以重写的,都是类对象方法
+(void)load+(void)initialize
注意:
使用第一次使用该类时,会先调用该类的父类的initialize方法
当有分类时,类和分类的load方法都会被调用;第一次使用该类时,只会调用分类的initialize方法。
类方法封装对象的创建
当实例化一个对象时,需要编写类似下面的代码:
Person*p=[[Personalloc]initWithAge:20];
这样的代码比较啰嗦,可以添加一个类方法来简化:
+(instancetype)personWithAge:(int)age{return[[Personalloc]initWithAge:age];}
这样实例化对象的代码为:
Person*p=[PersonpersonWithAge:20];
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。