我有一个覆盖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];
}
我知道这样做很好,但如果有人能解释我为什么会受到赞赏。
答案 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约定中,在初始化参数中使用'和'这个词有点过时了。