簡単な答え: コードを理解しやすく保守しやすくしたい場合は、常にの指定された初期化子を呼び出す必要があります。super
長い答え...
-[NSObject init]
メソッドは何もしないように文書化されています:
init
クラスで定義されたメソッドはNSObject
初期化を行いません。単純に を返しますself
。
したがって、理論的には、それを呼び出す必要はありません。実際には、コードをより均一にする (したがって理解しやすくする) ため、それを呼び出すことNSObject
をお勧めします。
いくつかの継承チェーンがあり、 とMyGrandparent > MyParent > MyObject
の両方の実装者であり、 のすべての初期化子をオーバーライドしない場合、初期化子から のオーバーライドされていない初期化子の1 つを直接呼び出すことができます。しかし、繰り返しますが、これは悪い考えです。あなたや他の誰かが後でコードを再検討しなければならないときに混乱し、後で実装を変更すると壊れる可能性があります。MyParent
MyObject
MyParent
MyGrandparent
MyGrandparent
MyObject
MyParent
また、複数のイニシャライザを作成している場合は、こことここで指定されたイニシャライザ について学ぶ必要があります。イニシャライザの 1 つを指定イニシャライザとして選択し、すべてのサブクラス イニシャライザがスーパークラスの指定イニシャライザを直接呼び出すようにすることが重要です。そうしないと、無限再帰が発生する可能性があります。この問題は、この回答とこの回答で徹底的に説明しました。
アップデート
あなたの例では、次のように指定された初期化子を設定できます。
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 は、カテゴリを onUIGestureRecognizerSubclass.h
で宣言するヘッダーでこれを行います。ForSubclassEyesOnly
UIGestureRecognizer
または、メソッドをサブクラスに公開することもできconfigureWith...
ます。おそらく、それらに初期化子をオーバーライドさせる必要さえないでしょう。