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

Instruments 指向传递给 的每个值LeakyClass以添加到数组 1。在此示例中object@"example"[NSURL URLWithString:exampleString]。Instruments 也指向callocs _array1_array2但我将它们都释放在dealloc.

我错过了什么吗?

4

2 回答 2

1

malloc/calloc 内存不计入引用,您强烈决定何时分配它以及何时释放它。将该指针设置为 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];

And don't free it, but instead set to nil wrapper1 and wrapper2.But even without overriding the dealloc method, you'll have all the memory freed after the object dies.

于 2012-12-06T14:44:29.050 回答
0

首先,使用__strong指针id是没有意义的,ARC 会尝试将release, retainetc 消息发送到指针,而不是每个对象(鉴于您当前的实现,它甚至不知道您动态分配了多少对象),所以,简而言之,无论有没有它,你都是一样的。至于泄漏,请尝试在分配之前释放指针。

无论如何,正如其他人提到的,为什么不使用NSArrayor/and NSDictionary

按照以下评论进行编辑:

当我说“无论有没有它你都一样”时,我的意思是,它不会以任何方式帮助你管理内存,它毫无意义。但是,您必须拥有所有权限定符,因此仅将其删除就会导致错误(正如您所报告的那样)。你应该使用

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

至于你的记忆问题,你free以前试过alloc吗?如果initWithCapacity:被调用两次会发生什么,我知道你不会调用两次,但不能保证仪器知道。

此外,这里还有一些规格供您更好地了解 ARC 和所有限定符。

于 2012-12-06T13:58:24.660 回答