1

C 配列を使用するとコードがリークするようですが、その理由がわかりません。

/* LeakyClass.m */

@property (nonatomic, assign) char **array1;
@property (nonatomic, assign) id __strong *array2;
@property (nonatomic, assign) unsigned short currentDictCount;

//...

- (id)initWithCapacity:(unsigned short)capacity
{
    if ((self = [super init])) {
        _array1 = (char **)calloc(sizeof(char*), capacity);  //Leak
        _array2 = (id __strong *)calloc(sizeof(id), capacity);  //Leak
    }
    return self;
}

- (void)dealloc {
    free(_array1);
    free(_array2);
    _array1 = NULL;
    _array2 = NULL;
}

- (void)addObjectToArray2:(id)object andCharToArray1:(char *)str
{
    [self array2][[self currentDictCount]] = object;
    [self array1][[self currentDictCount]] = str;

    [self setCurrentDictCount:[self currentDictCount] + 1];
}

@end

私はこれで呼び出しますLeakyClass

/* OtherClass.m */

LeakyClass *leaky = [[LeakyClass alloc] initWithCapacity:20];
[leaky addObjectToArray2:object andCharToArray1:"1"];  // Leak
[leaky addObjectToArray2:@"example" andCharToArray1:"2"];  /Leak
[leaky addObjectToArray2:[NSURL URLWithString:exampleString] andCharToArray1:"3"];  /Leak

計器は、配列 1 に追加するために渡された各値を指していLeakyClassます。この例ではobject@"example"[NSURL URLWithString:exampleString]. Instruments も と の s を指していますcallocが、 で両方を解放します。_array1_array2dealloc

何か不足していますか?

4

2 に答える 2

1

malloc/calloc メモリは ref カウントされません。いつ割り当てるか、いつ解放するかを強く決定します。そのポインタを NULL に設定しても解放されないため、free を使用します。

free(_array1); 
free(_array2);

これは dealloc メッセージに似ていますが、objective-c クラスではなく生のメモリを処理します。
生メモリもガベージ コレクタに含めたい場合は、NSData を使用してラップします。

@property (nonatomic,strong) NSData* wrapper1;
@property (nonatomic,strong) NSData* wrapper2;

データをラップします。

wrapper1= [NSData dataWithBytesNoCopy: _array1 length: capacity*sizeof(char*) freeWhenDone: YES];
wrapper2= [NSData dataWithBytesNoCopy: _array2 length: capacity*sizeof(id) freeWhenDone: YES];

それを解放しないで、wrapper1 と wrapper2 を nil に設定します。しかし、dealloc メソッドをオーバーライドしなくても、オブジェクトの終了後にすべてのメモリが解放されます。

于 2012-12-06T14:44:29.050 に答える
0

まず第一に__strong、ポインターを使用することidは無意味です。ARC は、各オブジェクトではなくポインターにrelease, retainetc メッセージを送信しようとします (現在の実装では、動的に割り当てたオブジェクトの数さえわかりません)。要するに、あなたはそれがあってもなくても同じです。リークに関しては、割り当ての前にポインターを解放してみてください。

とにかく、他の人が述べたように、NSArrayor/and を使用しないのはなぜNSDictionaryですか?

以下のコメントに従って編集します。

私が「それがあってもなくても同じだ」と言ったとき、それはあなたのメモリ管理に何の役にも立ちません. ただし、所有権修飾子が必要なので、それを削除するだけでエラーになります(報告したとおり)。使用する必要があります

@property (nonatomic, assign) id __unsafe_unretained *array2;

あなたの記憶の問題については、free以前にしようとしましたallocか? が 2 回呼び出されるとどうなるかinitWithCapacity:、2 回呼び出さないことはわかっていますが、インストゥルメントが知る保証はありません。

また、ARC とすべての修飾子をよりよく理解するための仕様もここにあります。

于 2012-12-06T13:58:24.660 に答える