1

まず第一に、なぜこの警告が存在するのか、理解できません。なぜこのような状況で警告が発せられるのか、説明できません。公式の Cocoa メモリ管理ポリシーは次のとおりです。 newObject、または mutableCopy)。

保持を使用してオブジェクトの所有権を取得できます」

私は次のようなコードがあることを知っています:

- (id) foo
{
    // do something
    return self;
}

- (id) init
{
    self = [super init];
    return [self foo]; // clang static analyzer is complaining about returning an object with a +0 retain count here, although a +1 would be expected
}

私の知る限り、これはclangによる誤検知ですよね? つまり、retain-count を増やす唯一のメソッドは「retain」と、名前が「alloc」、「new」、「copy」、または「mutableCopy」で始まるすべてのメソッドであるため、「init」は増加していません。保持カウントですが、クラスの「alloc」メソッドの戻り値を渡すために呼び出し元に中継されるため、実際には「init」は +1 ではなく +0 保持カウントを返すことが期待されます。そうじゃない?渡されたのと同じ保持カウントを持つオブジェクトを返すだけです。そのオブジェクトで「foo」を呼び出しても、保持カウントは変更されないため、このコードは完全に合法であり、実際には問題なく動作し、保持カウントは、プログラムの存続期間全体にわたって正確です。

4

2 に答える 2

4

慣例によるメソッド名fooは、呼び出し元が所有していないオブジェクトを返すことを意味します。

alloc-init***組み合わせは、呼び出し元が所有するオブジェクトを返します。

fooアナライザーは、実際に何をしているのかを確認するために内部を調べることができないか、わざわざ調べないように見えます。また、戻り値が既に所有されているオブジェクトと同じオブジェクトであることを認識していませんself

誤検知ではありません。サブクラス、または動的にロードされたカテゴリがfooをオーバーライドして、他のものを返す場合:

- (id) foo; {
    return [NSNumber numberWithInt:666];
}

そうすると、オブジェクトのリークselfとオーバーリリースが発生しNSNumberます。

于 2012-03-26T15:08:23.803 に答える
-1

はい、これは誤検知ですが、クラスを設計するときに使用するのは悪い習慣です。代わりに、fooを呼び出してから、次のようにselfを返す必要があります。

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

    return self;
}
于 2012-03-26T15:09:03.803 に答える