初始化-指定初始化
2015-06-28 20:57
288 查看
对象分配内存
+(id) alloc;
对象的诞生过程,主要是从操作系统获得一块足够大的内存,以存放该类的全部实例变量,并将其指定为存放内存对象的实力变量的位置。
alloc方法同时将这块内存全部设置为0。结果是:BOOL变量初始化为NO,所有的int类型变量为0,float变量为0.0,所有的指针为nil.
初始化对象
objective-c中有两种创建对象的不同方法
1.[类名 new];2.[[类名 alloc] init];
new方法是NSObject对象的一个静态方法,该方法实际上是alloc和init方法的组合,
实际上两者是一样的,但apple还是推荐我们使用第一种方法,因为使用第一种方法你可以定义的init方法来做一些初始化,当然,如果子类没有提供init方法,自然调用的就是父类的init方法了。所以说从安全的角度来看,作为开发者我们在对象使用之前一定要对对象进行初始化的,因此在定义类的时候要提供初始化方法。
- (id)init;
初始化的功能是保障我们的实例变量是可用的完整的对象,如:我们在初始化中给类中依赖的其他的实例变量赋值
有两种初始化思想,第一种初始化方法中将所有相依赖的对象全部创建并赋值,“开箱即用”;第二种是惰性赋值,就是在初始化的时候先占位,然后在使用的时候,再确认具体的值。这两种方法需要根据具体的业务来进行取舍。
初始化方法编写格式:
- (id)init { if (self = [super init]){ //do something init content.... } }
刚刚分配(alloc)的对象需要经过初始化才能使用
Car *car = [[Car alloc] init]; //但是不能这样写: `Car *car = [Car alloc];[car init];//wrong`
原因是初始化方法返回的对象可能与分配的对象不同
为什么init方法会返回不同的对象呢?
诸如NSString和NSArray这样的类实际上是类簇,由于init方法可以接收参数,因此,其代码能检查接收的参数,并决定返回类簇中哪一个类的对象更合适。比如,参数是 文本和参数是阿拉伯数字,返回的可能就是不同的类
编写初始化
`if (self = [super init]){便利初始化
- (id)initWithFormat:(NSStirng *)format,...;
初始化一个新的字符串作为格式化操作的结果。初始化方法命名时必须以initWith开头
NSString *string = [[NSString alloc] initWithFormat:@"%d or %d",12,23];
- (id)initWithContentOfFile:(NSString *)path encoding:(NSStringEncoding) enc error:(NSError ** )error;
用来打开指定路径上的文本文件,读取文件内容,并使用文件内容初始化一个字符串
例如:
NSError *error = nil; NSString *string = [[NSString alloc] initWithContentsOfFile:@"/tmp/words.txt" encoding:NSUTF8StirngEncoding error:&error];
功能是读取磁盘文件的内容,初始化一个字符串对象
encoding用于说明文件的内容的编码格式,比如:GBK UTF8等
error参数如果正常初始化了,则返回nil,否则返回错误的信息,这些信息封装成NSEror对象,可以使用%@格式符打印出来,也可以使用NSError的对象方法:localizedDescription打印错误信息。
注:error是指针的指针
指定初始化
便利初始化的缺点:
在子类化的时候,为了保证父类能正常初始化,就需要重写父类所有的初始化方法和便利初始化方法,并添加子类成员变量的初始化,这样就会导致,当父类修改或者添加初始化方法的时候,子类需要做相应的修改,这样的设计偏离了“高内聚低耦合”的设计原则指定初始化方法:
类中某个初始化方法被指派为指定初始化方法,该类的所有初始化方法都是用指定的初始化方法执行初始化操作。而子类使用其超类的指定初始化方法进行超类的初始化。一般情况下,接收参数最多的初始化方法最终的指定初始化方法,因为他的初始化信息比较全面。
在类中出现2个或者2个以上便利初始化方法时,把类的某个初始化方法指派为制定初始化方法,该类所有初始化方法使用指定初始化方法执行初始化操作,子类使用其超类的指定初始化方法实现超类的初始化方法操作,通常,接收参数最多的初始化方法,最终成为指定初始化方法
初始化方法规则
1.如果不需要设置任何状态,则不需要为你自己的类创建初始化方法2.如果初始化方法不止一个,则需要选择一个作为指定初始化方法
3.如果创建了一个指定初始化方法,则一定要在你自己的指定初始化方法中调用超类的指定初始化方法。其他的初始化方法使用指定初始化方法实现
代码实现:
- (id)init { self = [self initWithPressure:30.5f andTreadth:20.6f]; if (self) { } return self; } - (id)initWithPressure:(float)p { self = [self initWithPressure:p andTreadth:20.6f]; if (self) { } return self; } - (id)initWithTreadth:(float)t { self = [self initWithPressure:30.5f andTreadth:t]; if (self) { } return self; } //指定初始化方法 - (id)initWithPressure:(float)p andTreadth:(float)t { self = [super init]; if (self) { self.pressure= p; self.treadth = t; } return self; } }
相关文章推荐
- 戒烟周报
- C专家编程整理笔记
- spark、storm与Hadoop
- Ubuntu14.04安装配置SVN及Trac
- 令人堪忧的中国人的阅读
- 无监督学习的密度估计
- 黑马程序员——String
- FIO是测试IOPS的 支持13种不同的I/O引擎
- CentOS 初始化时普通用户修改ROOT密码并且开启远程登录
- 使用loadrunner进行压力测试之----post请求
- python中的面向对象编程
- 黑马程序员——面向对象(四)
- Python学习笔记 - function调用和定义
- Python学习笔记 - function调用和定义
- Android中ListView相关属性
- 黑马程序员——面向对象(三)
- 构造函数、析构函数和赋值函数
- LeetCode_Linked List_Linked List Cycle
- linux expect的简单用法及举例
- Isomorphic Strings