Objective-C 中便利初始化方法和指定初始化方法

时间:2020-12-24 15:25:51

初始化 之 便利初始化和指定初始化

便利初始化方式

便利初始化方式一
-(id) initWithFormat:(NSString *) format,...;   
  • 初始化了一个新的字符串作为格式化操作的结果. 下面就是一个小例子
//按格式返回字符串
NSString *myString = [[NSString alloc] initWithFormat:@"myString has %d
letter",8]; NSLog(@"%@",myString); 

其结果是打印出一句话: myString has 8 letter

便利初始化方式二
* -(id) initWithContentOfFile:(NSString*) path encoding:(NSStringEncoding) enc error:(NSError**)error
  • 功能是利用读取文件内容来初始化,初始化一个字符串对象
  • encoding 用于说明文件的编码格式,比如 GBK UTF8等,一般来说没有特殊情况,使用NSUTF8StringEncoding.
  • error 参数如果正常初始化了,则返回 nil, 否则返回错误信息,这些信息封装成 NSError 对象,可以使用%@格式符打印出来,也可以使用 NSError 的对象方法: localizedDescription 打印错误信息.
  • 注意: error 是指针的指针

下面是一个利用打开文件并且读取文件内容初始化的例子:

 NSError *error = nil;
 NSString *fileContent = [NSString stringWithContentsOfFile:@"/Users/qingyun/ Desktop/anotherTest.txt" encoding:NSUTF8StringEncoding error:&error];

NSString *fileContent = [[NSString alloc] initWithContentsOfFile:@"/Users/ qingyun/Desktop/anotherTest.txt" encoding:NSUTF8StringEncoding error:&error];
      // error 是指针的指针 
   if (nil != error) {
       NSLog(@"%@",error);
       exit(1);
   }
NSLog(@"File content:%@",fileContent);

指定初始化方式

便利构造函数的缺点

  
   在子类化的时候,为了保证父类能正常初始化,就需要重写父类所有的初始化方法和便利初始化方法,并添加子类成员变量的初始,这样就会导致,当父类修改或者添加初始化方法的时候,子类需要做相应的修改。这样的设计偏离了高内聚低耦合的设计原则。

指定初始化函数

   类中的某个初始化方法被指派为指定初始化函数,该类的所有初始化方法都使用指定初始化方法执行初始化操作.而子类使用其超类的指定初始化方法进行超类的初始化.
   一般情况下,接收参数最多的初始化方法是最终的指定初始化方法,因为它的初始化信息比较全面.因此,对于子类来说,只要重写父类的指定初始化方法,就可以解决便利初始化方法的缺点.

下面举一个例子,构建一个 QYTire 的类,它有两个成员变量,压力和花纹,还有一些对应的方法,在其对应的头文件(. h) 中,代码如下: 

#import <Foundation/Foundation.h>

@interface QYTire : NSObject
//{
// float myTirePresure;
//}
@property float pressure;
@property float treadth;

- (id)initWithPressure:(float)pressure;
- (id)initWithTreadth:(float)treadth;


- (id)initWithPressure:(float)pressure andTreadth:(float)treadth;
@end

在实现文件中,代码如下:

- (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;
        _treadth = t;
    }
    return self;
}

新建一个子类 AllWeatherTire,继承于 QYTire,由于它继承了超类中的方法,当其在子类中要使用这些方法时,要重写这些方法.如果使用指定初始化方法时,当父类方法出现变动时,只需要重写子类中的指定初始化方法即可.

//头文件AllWeatherTire.h
#import "QYTire.h"

@interface AllWeatherTire : QYTire
//{
// float rainHanding;
// 
//}
@property float rainHanding;
@property float snowHanding;

- (id)initWithRainHanding:(float)rainHanding;
- (id)initWithSnowHanding:(float)snowHanding;

@end


//实现文件AllWeatherTire.m
#import "AllWeatherTire.h"

@implementation AllWeatherTire

- (id)initWithPressure:(float)p andTreadth:(float)t
{
    self = [super initWithPressure:p andTreadth:t];
    if (self) {
        self.snowHanding = 300.2f;
        self.rainHanding = 200.3f;
    }
    return self;
}
- (id)initWithSnowHanding:(float)s
{
    self = [self initWithSnowHanding:s  andRainHanding:200.3f];
    if (self) {

    }
    return self;
}

- (id)initWithRainHanding:(float)r
{
    self = [self initWithSnowHanding:300.2f andRainHanding:r ];
    if (self) {

    }
    return self;
}

// 子类的也可以使用指定初始化方式
- (id)initWithSnowHanding:(float)s andRainHanding:(float)r
{
    self = [super init];
    if (self) {
        self.snowHanding = s;
        self.rainHanding = r;
    }
    return self;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"%.1f,%.1f,%.1f,%.1f", [self pressure] ,[self treadth],self.rainHanding,self.snowHanding];
}

@end