web-dev-qa-db-ja.com

iOS:UIViewサブクラスinitまたはinitWithFrame :?

固定フレームを持つUIViewのサブクラスを作成しました。したがって、initWithFrame:の代わりにinitをオーバーライドできますか?例えば。:

- (id)init {
    if ((self = [super initWithFrame:[[UIScreen mainScreen] bounds]])) {
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

-initWithFrame:のXcodeドキュメントには、「プログラムでビューオブジェクトを作成する場合、このメソッドはUIViewクラスの指定イニシャライザです。サブクラスはこのメソッドをオーバーライドしてカスタム初期化を実行できますが、super実装の開始時。」

「指定イニシャライザー」とはどういう意味ですか?

37
ma11hew28

指定された初期化子は、他のすべての初期化子が呼び出す必要があるものです。 UIViewとサブクラスは、ビューの作成方法に応じて、-initWithFrame:-initWithCoder:という2つの初期化子を実際に持っているという点で、少し変わっています。ビューをコードでインスタンス化する場合は-initWithFrame:をオーバーライドし、ペン先からビューをロードする場合は-initWithCoder:をオーバーライドする必要があります。または、コードを3番目のメソッドに入れ、これらの初期化子をオーバーライドして、3番目のメソッドを呼び出すようにすることもできます。実際、それはしばしば推奨される戦略です。

したがって、たとえば、独自の初期化メソッド-initWithPerson:place:thing:を持つUIViewサブクラスClueCharacterを作成できます。次に、次のようにビューを作成します。

Obj-C:

ClueCharacter *mustard = [[ClueCharacter alloc] initWithPerson:@"Col. Mustard"
                                                         place:kInTheStudy
                                                         thing:kTheRope];

迅速:

var mustard = ClueCharacter("Col. Mustard", place: kInTheStudy, thing: kTheRope)

それは問題ありませんが、オブジェクトのUIView部分を初期化するために、メソッドmustは指定された初期化子を呼び出します:

Obj-C:

-(id)initWithPerson:(NSString*)name place:(CluePlace)place thing:(ClueWeapon)thing
{
    if ((self = [super initWithFrame:CGRectMake(0, 0, 150, 200)])) {
        // your init stuff here
    }
}

迅速:

func init(name: String, place : CluePlace, thing : ClueWeapon)
{
    if (self = super.init(CGRectMake(0, 0, 150, 200))) {
       // your init stuff here
    }
}

サブクラスの初期化子-initを呼び出したい場合、実装で-initWithFrame:を呼び出していれば問題ありません。

73
Caleb

UIViewの呼び出し[super init][super initWithFrame:CGRectZero]と正確に等しい

23
user1411443

複数の初期化子を持つObjective-Cクラスでは、指定された初期化子が意味のある作業を行います。そのため、多くの場合、いくつかの初期化子を持つクラスがあります。

- (id)initWithRect:(CGRect)someRect;

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour;

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour
             linkTo:(id)someOtherObject;

その場合、通常(常にではありませんが)3番目が指定された初期化子であると言い、他の2つを実装します。

- (id)initWithRect:(CGRect)someRect
{
    return [self initWithRect:someRect setDefaultColour:NO];
}

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour
{
    return [self initWithRect:someRect setDefaultColour:setDefaultColour
                   linkTo:nil];
}

クラスに初期化子が1つしかない場合、それが指定された初期化子です。

ベストプラクティスに従う場合は、initWithFrame:およびバニラinit:を呼び出すinitWithFrame:通常の寸法で。通常の慣例では、サブクラスのinitに新しいバリエーションを追加できますが、取り去ってはならず、指定された初期化子で実際の初期化作業を常に実行します。これにより、サブクラスで適切に動作するために、まだ新しい実装を提供しない親クラスからの初期化メソッドが許可されます。

3
Tommy