当重写`init`方法时,为什么重新定义它很重要?

时间:2013-02-18 05:42:05

标签: objective-c

我有一个覆盖init方法的练习,所以我需要创建一个init方法来设置一些属性。

我的问题是:为什么我还需要定义原始init方法?如果新的init方法不起作用?

这是我的.h文件:

#import <Foundation/Foundation.h>

#import "XYPoint.h"

@interface Rectangle: NSObject

@property float width, height, tx, ty;

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
-(void) translate: (XYPoint *) point;
-(id) initWithWidth:(int) w andHeight:(int) h;
-(id) init;

@end

.m(只有init方法):

-(id) initWithWidth:(int)w andHeight:(int)h
{
    self = [super init];

    if (self)
    {
        [self setWidth:w andHeight:h];
    }

    return self;
}

-(id) init
{
    return [self initWithWidth:0 andHeight:0];
}

我知道这样做很好,但如果有人能解释我为什么会受到赞赏。

2 个答案:

答案 0 :(得分:5)

我们的想法是为您的对象建立一个初始化的初始点,而不是在每个init方法中为变量初始化。

您的特定示例对此模式没有多大帮助,因为您正在初始化0宽度和0高度的Rectangle,并且默认NSObject实现默认情况下将所有实例变量的内存重置为零,并且{{ 1}}方法也是如此。但是,假设您在使用时创建Rectangle对象时默认分配单位矩形(宽度1,高度1),

initWithWidth:andHeight:

然后而不是这样做,

[[Rectangle alloc] init]

你只是通过这样做来集中初始化点,

- (id)initWithWidth:(int)width andHeight:(int)height {
    self = [super init];
    if (self) {
        [self setWidth:width andHeight:height];
    }
    return self;
}

- (id)init {
    self = [super init];
    if (self) {
        [self setWidth:1 andHeight:1];
    }
    return self.
}

这也与DRY a.k.a的原则密切相关。不要重复自己。

这是一个简单的例子,但是,在大多数现实世界的对象中,您可能会有更复杂的设置,包括通知注册,KVO注册等,然后集中所有初始化逻辑变得至关重要。

答案 1 :(得分:2)

你没有。您通常有一个调用super的初始化程序(self = [super initWithXX]),其他的初始化程序则调用super。

在上面的具体示例中,它是一个好主意,因为initWithWidth:andHeight充当主初始化器,因此如果您调用默认值,那么需要在主初始化程序中运行的代码将被调用。

顺便说一句:在现有的Objective-C约定中,在初始化参数中使用'和'这个词有点过时了。