9

この状況に対処する方法に関する一般的なガイダンスを探しています。これが具体的な例です。

私は UIImageView をサブクラス化しており、initWithImage をオーバーライドして、提供されたイメージでスーパークラス自体を初期化した後、独自の初期化コードを追加したいと考えています。

ただし、UIImageView の指定されたイニシャライザは文書化されていないため、サブクラスが正しく初期化されるようにするには、どのスーパー クラス イニシャライザを呼び出す必要がありますか?

クラスが初期化子を指定していない場合は、次のことを行います。

  1. クラスの (UIImageView) 初期化子を呼び出しても安全だと思いますか?
  2. 指定されたイニシャライザのスーパー クラス (UIView) を参照してください。

この場合、オーバーライドされたイニシャライザで次のことを行うのが理にかなっているため、#1 が答えになるようです。

- (id)initWithImage:(UIImage *)image
{
    self = [super initWithImage:image];
    if (self) {
        // DO MY EXTRA INITIALIZATION HERE
    }
    return self;
}
4

5 に答える 5

5

UIImageView には 2 つの初期化子があるため、サブクラスがこれらの初期化パスの両方を処理することを確認する必要がある場合があります。

-initWithImage:指定された初期化子であると宣言するだけで、他のすべての初期化子はサポートされません。

さらに、-initWithImage:highlightedImage:サポートされていないことを示す例外を実装してスローすることもできます。

-initWithImage:highlightedImage:または、指定イニシャライザとして宣言し、指定イニシャライザを-initWithImage:呼び出すこともできます。

または、クラスがまたは-initWithImage:で初期化されているかどうかに関係なく、初期化子が呼び出されることがあります。-initWithImage:-initWithImage:highlightedImage:

于 2012-10-30T20:32:53.593 に答える
4

UIImageView のドキュメントはひどいものです。2 つの初期化子が示されていますが、どちらも呼び出されない状況に陥ることがあります。たとえば、私は IB を使用していて、initWithCoder:呼び出されるだけです。

- (id)init
{
    return [super init];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    return [super initWithCoder:aDecoder];
}

- (id)initWithFrame:(CGRect)frame
{
    return [super initWithFrame:frame];
}

- (id)initWithImage:(UIImage *)image
{
    self = [super initWithImage:image];
    return self;
}

- (id)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage
{
    self = [super initWithImage:image highlightedImage:highlightedImage];
    return self;
}

UIImageView をサブクラス化する唯一の正しい方法は、すべてのイニシャライザをサブクラス化することであり、各サブクラスは親のイニシャライザを同じ名前でのみ呼び出すことができます。例えば:

subclass -initを呼び出すことはできますUIImageView -initが、呼び出すことはできませんUIImageView -initWithCoder:

はい、指定がないのは本当に痛いです。

于 2013-10-07T22:21:35.677 に答える
1

から派生するすべてのクラスには、そのオブジェクトの初期化プロセスを実行する 1 つのイニシャライザとしてのメソッドがありますNSObjectinitしたがって、よくわからない場合はself = [super init]、カスタム初期化子でいつでも使用できます。Apple が提供する 2 つの初期化子があるという事実を考慮すると、UIImageView両方をオーバーライドするか、このメソッドを使用できないという例外をユーザーにスローする必要がある場合があります (推奨されません)。

例:-

- (id)initWithCustomParam:(NSString *)param {

    if (self = [super init]) {
        self.myparam = param;
    }
    return self;
}

そして、他のイニシャライザを次のように実装できます。

- (id)initWithImage:(UIImage *)image {

    if (self = [self initWithCustomParam:@"default value"]) {
        self.image = image;
    }
    return self;
}

または定義し、

- (id)initWithImage:(UIImage *)image customParam:(NSString *)string {

    if (self = [self initWithCustomParam:string]) {
        self.image = image;
    }
    return self;
}
于 2012-10-30T21:36:32.757 に答える