【IOS 开发学习总结-OC-15】objective-c面向对象之——对象初始化
2015-09-24 10:03
716 查看
创建对象有2种方法(本质是一样的,都是用 alloc 方法为对象分配内存空间)。
1.
2.
调用某个类的alloc 方法方法时,系统完成的2件事情:
1. 系统为该类的所有实例变量分配内存空间
2. 将每个实例变量的内存空间都重置为”0”。这个0,是广义上的0——所有整型变量所在空间重置为0;所有浮点变量的重置为0.0;所有 BOOL型变量都重置为 NO;所有指针类型变量都重置为 nil。
仅仅分配内存空间的对象还不能使用,必须先对该对象执行初始化后才能使用。OC 中最常用的初始化方法来自 NSObject的 init,所以呢,所有的类都可以调用该方法进行初始化。
示例代码:
FKUser.h
FKUser.m
FKUserTest.m
编译运行后,结果为:
说明:这里用到的 init 方法不是NSObject 提供的,是FKUser.m中提供的。
示例代码:
FKCar.h
FKCar.m
FKCarTest.m
编译运行后的结果:
值得一提的是上面例子中有很好的代码复用。如果系统中包含了过个初始化方法,其中一个初始化方法执行体中完全包含另一个初始化方法的执行体,这样就可以进行代码复用。
如上图,初始化方法B中完全包含了初始化A。此时就可以直接在初始化方法 B 中调用初始化方法,实现代码复用,就像上面的栗子中做的那样。
1.
[[类名 alloc]init];
2.
[类名 new];
为对象分配内存空间
我们知道无论创建哪个对象,总需要先调用该类的 alloc 类方法来分配内存,这个alloc 类方法来自 NSObject, 而所有的 objective-c 类都是NSObject的子类。所以,所有的类都可以调用 alloc 方法来进行分配空间。调用某个类的alloc 方法方法时,系统完成的2件事情:
1. 系统为该类的所有实例变量分配内存空间
2. 将每个实例变量的内存空间都重置为”0”。这个0,是广义上的0——所有整型变量所在空间重置为0;所有浮点变量的重置为0.0;所有 BOOL型变量都重置为 NO;所有指针类型变量都重置为 nil。
仅仅分配内存空间的对象还不能使用,必须先对该对象执行初始化后才能使用。OC 中最常用的初始化方法来自 NSObject的 init,所以呢,所有的类都可以调用该方法进行初始化。
初始化方法与对象初始化
init方法只是完成最基本的初始化,对象的所有成员变量依然是0。实际的编程中,我们可以重写 init 方法,满足自定义处理代码的需要。示例代码:
FKUser.h
#import <Foundation/Foundation.h> @interface FKUser : NSObject // 使用@property定义3个属性 @property (nonatomic , copy) NSString* name; @property (nonatomic , assign) int age; @property (nonatomic , copy) NSString* address; @end
FKUser.m
#import "FKUser.h" @implementation FKUser @synthesize name; @synthesize age; @synthesize address; // 重写init方法,完成自定义初始化 - (id) init { // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象 // 如果self不为nil,表明父类init方法初始化成功 if(self = [super init]) { // 对该对象的name、age、address赋初始值 self.name = @"孙悟空"; self.age = 500; self.address = @"花果山,水帘洞"; } return self; } @end
FKUserTest.m
#import "FKUser.h" int main(int argc , char * argv[]) { @autoreleasepool{ // 创建并初始化FKUser对象 FKUser* user = [[FKUser alloc] init]; // 访问FKUser对象的属性 NSLog(@"user的name为%@" , user.name); NSLog(@"user的age为%d" , user.age); NSLog(@"user的address为%@" , user.address); } }
编译运行后,结果为:
2015-09-24 13:54:11.596 923[6428:316945] user的name为孙悟空 2015-09-24 13:54:11.597 923[6428:316945] user的age为500 2015-09-24 13:54:11.598 923[6428:316945] user的address为花果山,水帘洞
说明:这里用到的 init 方法不是NSObject 提供的,是FKUser.m中提供的。
便利的初始化方法
实际中,我们会根据需要为 objective-c 类提供很多以 init 开头,并允许自带一些参数的便利的初始化方法。示例代码:
FKCar.h
#import <Foundation/Foundation.h> @interface FKCar : NSObject // 使用@property定义3个属性 @property (nonatomic , copy) NSString* brand; @property (nonatomic , copy) NSString* model; @property (nonatomic , copy) NSString* color; // 定义initWithBrand: model:方法,完成自定义初始化 - (id) initWithBrand:(NSString*) brand model:(NSString*) model; // 定义initWithBrand: model: color:方法,完成自定义初始化 - (id) initWithBrand:(NSString*) brand model:(NSString*) model color:(NSString*) color; @end
FKCar.m
#import "FKCar.h" @implementation FKCar @synthesize brand = _brand; @synthesize model = _model; @synthesize color = _color; // 重写init方法,完成自定义初始化 - (id) init { // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象 // 如果self不为nil,表明父类init方法初始化成功 if(self = [super init]) { // 对该对象的brand、model、color赋初始值 self.brand = @"奥迪"; self.model = @"Q5"; self.color = @"黑色"; } return self; } // 实现initWithBrand: model:方法,完成自定义初始化 - (id) initWithBrand:(NSString*) brand model:(NSString*) model { // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象 // 如果self不为nil,表明父类init方法初始化成功 if(self = [super init]) { // 对该对象的brand、model、color赋初始值 self.brand = brand; self.model = model; self.color = @"黑色"; } return self; } // 实现initWithBrand: model: color:方法,完成自定义初始化 - (id) initWithBrand:(NSString*) brand model:(NSString*) model color:(NSString*) color { // 调用本类的initWithBrand: model:方法执行初始化,将初始化得到的对象赋值给self对象 // 如果self不为nil,表明initWithBrand: model:方法初始化成功 if(self = [self initWithBrand:brand model:model]) { // 对该对象的color赋初始值 self.color = color; } return self; } @end
FKCarTest.m
#import "FKCar.h" int main(int argc , char * argv[]) { @autoreleasepool{ // 创建并初始化FKCar对象 FKCar* car1 = [[FKCar alloc] init]; // 访问car1对象的属性 NSLog(@"car1的brand为%@" , car1.brand); NSLog(@"car1的model为%@" , car1.model); NSLog(@"car1的color为%@" , car1.color); // 创建并初始化FKCar对象 FKCar* car2 = [[FKCar alloc] initWithBrand:@"奔驰" model:@"ML350"]; // 访问car1对象的属性 NSLog(@"car2的brand为%@" , car2.brand); NSLog(@"car2的model为%@" , car2.model); NSLog(@"car2的color为%@" , car2.color); // 创建并初始化FKCar对象 FKCar* car3 = [[FKCar alloc] initWithBrand:@"宝马" model:@"X5" color:@"BLACK"]; // 访问car1对象的属性 NSLog(@"car3的brand为%@" , car3.brand); NSLog(@"car3的model为%@" , car3.model); NSLog(@"car3的color为%@" , car3.color); } }
编译运行后的结果:
2015-09-24 14:01:03.652 923[6499:322947] car1的brand为奥迪 2015-09-24 14:01:03.656 923[6499:322947] car1的model为Q5 2015-09-24 14:01:03.657 923[6499:322947] car1的color为黑色 2015-09-24 14:01:03.658 923[6499:322947] car2的brand为奔驰 2015-09-24 14:01:03.658 923[6499:322947] car2的model为ML350 2015-09-24 14:01:03.659 923[6499:322947] car2的color为黑色 2015-09-24 14:01:03.659 923[6499:322947] car3的brand为宝马 2015-09-24 14:01:03.660 923[6499:322947] car3的model为X5 2015-09-24 14:01:03.660 923[6499:322947] car3的color为BLACK
代码复用
知识切入:值得一提的是上面例子中有很好的代码复用。如果系统中包含了过个初始化方法,其中一个初始化方法执行体中完全包含另一个初始化方法的执行体,这样就可以进行代码复用。
如上图,初始化方法B中完全包含了初始化A。此时就可以直接在初始化方法 B 中调用初始化方法,实现代码复用,就像上面的栗子中做的那样。
开发者重写初始化方法的模板
- (id) init { // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象 // 如果self不为nil,表明父类init方法初始化成功 if(self = [super init]) { //执行初始化 } return self; }
相关文章推荐
- POJ 3241 曼哈顿距离最小生成树 Object Clustering
- Objective-C基础语法(一)
- Objective-C---2---初始化、便利构造器
- SpannableStringBuilder连续调用setSpan时参数Object what不能使用同一个引用
- Object-C 字符串截取、匹配、分割
- 深入分析iOS问题-performSelector:onThread:withObject:waitUntilDone
- Copy vs Retain in Objective C
- Objective-C之property属性分析
- Objective-C type encodings
- struts2 Map<String,Object>session心得 浅析
- Mybatis之配置文件中的objectFactory节点内容说明
- 打开页面出现Object reference not set to an instance of an object错误
- 关于swift与objective-c混合编译
- Objective-C入门20:Block
- 在java代码里写Map<String, ?>和Map<String, Object>都是可以用的,他们两个有什么区别?
- Objective-C Runtime Messaging
- 改善Objective-C的日志输出
- Objective-C入门18:KVO
- QMetaObject之invokeMethod说明和使用
- Object-c基础语法