简短的回答:如果您希望您的代码易于理解和维护,那么您必须始终调用super
's 指定的初始化程序。
长答案...
该-[NSObject init]
方法被记录为什么都不做:
init
类中定义的方法NSObject
没有初始化;它只是返回self
。
因此理论上你不需要调用它。在实践中,最好调用它,因为它使您的代码更加统一(因此更容易理解),并且如果您决定将类更改为继承自NSObject
.
如果你有一些继承链MyGrandparent > MyParent > MyObject
,并且你是 and 的实现者MyParent
,MyObject
并且MyParent
没有覆盖所有MyGrandparent
的初始化器,那么你可以直接MyGrandparent
从你的初始化器中调用一个非覆盖的初始化MyObject
器。但同样,这是一个坏主意。当您或其他人稍后必须重新访问代码时,这会令人困惑,并且如果您MyParent
稍后更改实现,则可能会中断。
此外,如果您要创建多个初始化程序,则需要了解指定初始化程序 here和here。选择一个初始化器作为指定初始化器很重要,并确保所有子类初始化器直接调用超类的指定初始化器。否则,您最终可能会创建无限递归。我在这个答案和这个答案中彻底解释了这个问题。
更新
在您的示例中,您可以像这样设置指定的初始化程序:
static CGFloat const kMaximumDimensionNone = 0; // or NAN if 0 is a valid max dimension
static CGSize const kSizeNone = { 0, 0 }; // or NAN, NAN if 0x0 is a valid size
- (id)initWithGraphic:(Graphic *)graphic size:(CGSize)size maximumDimension:(CGFloat)maximumDimension {
if (self = [super init]) {
_graphic = graphic;
if (!CGSizeEqualToSize(size, kSizeNone)) {
[self configureWithSize:size];
}
else if (maximumDimension != kMaximumDimensionNone) {
// Use if(!isnan(maximumDimension)) instead if you use NAN as the placeholder
[self configureWithMaximumDimension:maximumDimension];
}
else {
[self configureWithDefaultDimensions];
}
}
return self;
}
- (id)initWithGraphic:(Graphic *)graphic {
return [self initWithGraphic:graphic size:kSizeNone maximumDimension:kMaximumDimensionNone];
}
- (id)initWithGraphic:(Graphic *)graphic size:(CGSize)size {
return [self initWithGraphic:graphic size:size maximumDimension:kMaximumDimensionNone];
}
- (id)initWithGraphic:(Graphic *)graphic maximumDimension:(CGFloat)maximumDimension {
return [self initWithGraphic:graphic size:kSizeNone maximumDimension:kMaximumDimensionNone];
}
您不必在公共头文件中公开指定的初始化程序。您可以添加一个单独的头文件,为要导入的子类公开指定的初始化程序。例如,Apple 使用标题来执行此操作,该UIGestureRecognizerSubclass.h
标题ForSubclassEyesOnly
在UIGestureRecognizer
.
或者您可以将这些configureWith...
方法公开给您的子类,甚至不需要让它们覆盖初始化程序。