对象分配内存
+(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;
}
}