4

我有一个重写 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];
}

我知道这样很好,但是如果有人可以解释我为什么会这样,我将不胜感激。

4

2 回答 2

5

这个想法是为您的对象设置一个初始化的中心点,而不是在每个 init 方法中散布变量的初始化。

您的特定示例对这种模式没有多大的公平,因为您正在初始化一个宽度为 0 高度为 0 的 Rectangle,并且默认 NSObject 实现默认将所有实例变量的内存重置为零,您的initWithWidth:andHeight:方法也是如此。但是,假设您在使用创建 Rectangle 对象时默认分配单位矩形(宽度 1,高度 1),

[[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.
}

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

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

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

这也与DRY aka Don't Repeat Yourself 的原则密切相关。

这是一个微不足道的例子,然而,在大多数现实世界的对象中,您可能有一个更复杂的设置,包括通知注册、KVO 注册等,然后集中所有初始化逻辑就变得非常重要。

于 2013-02-18T06:04:09.887 回答
2

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

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

顺便说一句:根据现代 Objective-C 约定,在初始化参数中使用“和”这个词有点过时。

于 2013-02-18T05:52:03.007 回答