3

Xcode (4.5.2) 静的アナライザーが明らかにリークを検出しない次の最小限の例をまとめました。これは、静的アナライザーについて行ったいくつかの観察を検証するためです。

#import <Foundation/Foundation.h>

@interface Foo : NSObject {
    NSArray *array;
}
@property (nonatomic, retain) NSArray *array;
- (void)bar;
@end

@implementation Foo
@synthesize array;
- (void)bar
{
    // Shouldn't the static analyzer flag this as a leak?
    array = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}
@end

int main(int argc, const char *argv[])
{
    @autoreleasepool {
        Foo *foo = [[Foo alloc] init];

        [foo bar];
        [foo bar];
        [foo bar];

        [foo release];
    }

    return 0;
}

私が間違っていなければ、繰り返し呼び出すとインスタンスbarがリークします。その名前がそうしないことを意味する場合、+1 保持カウントでインスタンスを作成します。以前にインスタンス変数に割り当てられたインスタンスは解放されないため、リークされます。NSArraybarNSArrayarray

しかし、本当に気になるのは、ARC が基本的に静的アナライザーと同じアルゴリズムを使用していることをどこかで読んだことです。これは、このコードが ARC でもリークするということですか? __strongそれとも、修飾子や対応する(strong)プロパティがなくても、ARC はすべてのインスタンス変数をデフォルトで強力なものとして扱いますか?

4

1 に答える 1

5

円弧なし:

配列はインスタンス変数であるため、リークは検出されません。インスタンス変数配列は引き続きアクセス可能で有効であるため、保持カウントが 1 のオブジェクトに割り当てることはリークとは見なされません。
そのメソッドを複数回呼び出したとしても、静的アナライザーは、配列が保持された変数を指していたことを知るだけでは十分ではありません。
静的アナライザーは、単一のメソッドでオブジェクトがいつリークされたかを知るのに役立ちます。
しかし、そのようにメソッドを変更してみてください:

- (void)bar
{
    // Shouldn't the static analyzer flag this as a leak?
    NSArray* array2 = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}

これは、静的アナライザーによって検出されます。

アークについて

ARC では、このコードはリークしていませんでした。これは、 array= と言うと、次のようになるためです。

  1. リリース配列:
  2. 新しく作成されたオブジェクトを保持します。
  3. インスタンス変数に割り当てます。

可能であれば、ARCに目を向けることをお勧めします。

于 2012-12-09T22:22:59.227 に答える