1

我的代码似乎在使用C数组时泄漏,我不知道为什么。启用了ARC的泄漏

/* 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 

仪器都指向每个传递到LeakyClass值的要添加到阵列1在这个例子中,object@"example"[NSURL URLWithString:exampleString]。仪器也指向calloc s为_array1_array2,但我免费他们两个在dealloc

我错过了什么吗?

+0

你为什么不使用'NSMutableArrays'? – Ismael

+0

不仅如此,这看起来像是一个'NSMutableDictionary'的基本实现。你为什么这样做? – WDUK

+1

的确,他可以使用Objective-C类,但我认为这对于初学者来说是一个很好的练习来尝试这些事情。 –

回答

0

全部采用__strongid指针首先是没有意义的,ARC会尝试将releaseretain等消息发送到指针,而不是对你们每一个人的对象(鉴于你目前的实现中,它甚至不知道有多少对象,你动态分配),所以,总之,你是相同的或不相同。至于泄漏,尝试在alloc之前释放指针。

无论如何,正如其他人所说,为什么不使用NSArray或/和NSDictionary

编辑遵循以下意见:

当我说:“你带或不带它相同的”我的意思是,它不会帮助你与你的内存管理的任何方式,这是毫无意义的。但是,您必须拥有所有权限定符,因此删除它最终会出现错误(如您所报告的)。您应该使用

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

至于你的内存有问题,你有没有alloc之前试图free?如果initWithCapacity:被调用两次会发生什么,我知道你不会再调用它两次,但不能保证仪器知道。

另外here是您了解更好的ARC和所有限定符的规格。

+0

这并不完全如此。在这种情况下删除'__strong'会导致编译错误。 –

+0

如果删除它,会得到什么错误? –

+0

'指向非const型'id'的指针,没有明确的所有权.' –

1

的malloc /释放calloc内存不计入裁判,你强烈决定何时分配它,什么时候取消分配it.Setting该指针为NULL并不会释放它,使用免费的:

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。但是即使没有重写dealloc方法,在对象死亡后你也将释放所有内存。

+0

我会马上试试这个。我已经释放dealloc中的数组,但我会尝试与NSData,看看它是否停止泄漏。 –

+0

此代码完美工作,并修复了数组泄漏问题。谢谢!你有没有想过为什么要传入的数组插入array2(参见问题底部)的对象正在泄漏? –

+0

因为_array2具有强引用,并隐式保留所有对象。 –