3

アップグレードしてから、アナライザーの警告が表示されます...

Returning 'self' while it is not set to the result of '[(super or self) init...]'

何が悪いのかわからない?

- (id)initWithFrame:(CGRect)frame {
    if (self == [super initWithFrame:frame]) {
        [self initLayers];
    }
    return self;
}
4

3 に答える 3

13

2 番目の等号を取り除きます。適切なifステートメントは次のとおりです。

if(self = [super initWithFrame:frame])

これのポイントは、スーパー実装が、self の現在の値とは異なるが有効なオブジェクトを返す可能性があるということです。この場合、オブジェクトが異なるため、if ステートメントは false になり、初期化は行われません。ただし、別のオブジェクトが返されたため、スーパー実装は古い自己を解放しているはずです。これが返されます。これは、おそらく無効なポインターを返していることを意味します。

等号を 1 つだけ使用すると、変数を比較する代わりに変数を設定できます。ではないif(object)場合は が真であるため、これは次と同等です。objectnil

if((self = [super initWithFrame:frame]) != nil)

または、理解しやすいバージョン:

self = [super initWithFrame:frame];
if(self != nil)

このコードselfは、返された値が同じであると仮定するのではなく、スーパーイニシャライザによって返された値になるように再割り当てします。init...これは、変数をメソッドの結果ではなく、結果に設定することが重要である理由と同じallocです。

// good
id object = [[MyClass alloc] init];
// bad
id object = [MyClass alloc];
[object init];
于 2011-11-09T22:13:36.360 に答える
3

私の記憶が正しければ、構文はself = ...notself == ...です。構文は代入からの戻り値を使用します。

于 2011-11-09T22:06:25.953 に答える
2

あなたの戻ってきた自己は初期化されていません

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initLayers];
    }
    return self;
}
于 2011-11-09T22:06:02.847 に答える