web-dev-qa-db-ja.com

サブクラスでのinitのオーバーライド

Objective-Cでは、サブクラスの継承されたすべてのコンストラクターをオーバーライドしてカスタム初期化ロジックを追加する必要がありますか?

たとえば、カスタム初期化ロジックを使用したUIViewサブクラスの場合、以下は正しいでしょうか?

@implementation CustomUIView

- (id)init {
    self = [super init];
    if (self) {
        [self initHelper];
    }
    return self;
}

- (id)initWithFrame:(CGRect)theFrame {
    self = [super initWithFrame:theFrame];
    if (self) {
        [self initHelper];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super initWithCoder:decoder];
    if (self) {
        [self initHelper];
    }
    return self;
}

- (void) initHelper {
    // Custom initialization
}

@end
38
hpique

すべてのCocoa Touch(およびCocoa)クラスには、指定された初期化子があります。 UIViewの場合、前述のとおり このドキュメントで 、そのメソッドはinitWithFrame:。この特定のケースでは、オーバーライドする必要があるのはinitWithFrame;のみです。他のすべての呼び出しはカスケードされ、最終的にこのメソッドにヒットします。

これは質問の範囲を超えていますが、追加のパラメーターを使用してカスタム初期化子を作成することになった場合は、selfを割り当てるときに、スーパークラスの指定された初期化子を確認する必要があります。

- (id)initWithFrame:(CGRect)theFrame puzzle:(Puzzle *)thePuzzle title:(NSString *)theTitle {
    self = [super initWithFrame:theFrame];
    if (self) {
        [self setPuzzle:thePuzzle];
        [self setTitle:theTitle];
        [self initHelper];
    }
    return self;
}
41
Sam Ritchie

Interface Builderを使用する場合、その名前は次のとおりです。

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
       //do sth
    }
    return self;
}
4
letanthang

一般に、指定された初期化規則に従う必要があります。指定された初期化子はinitであり、すべてのインスタンス変数の初期化をカバーします。指定された初期化子は、クラスの他のinitメソッドによって呼び出されるメソッドでもあります。

Appleの ドキュメント 指定された初期化子について。

initWithFrame:は、NSViewクラスの指定された初期化子です。 AppleのCocoaドキュメントには、クラスの指定された初期化子が常に明示的に記載されています。

initWithCoder:について説明します ここSO

4