使用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
乐器指向传递到LeakyClass
的每个值以添加到数组1.在此示例中,object
,@"example"
和[NSURL URLWithString:exampleString]
。乐器也指向calloc
和_array1
的{{1}},但我在_array2
中释放了它们。
我错过了什么吗?
答案 0 :(得分: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];
并且不要释放它,而是设置为nil wrapper1和wrapper2.But即使没有覆盖dealloc方法,你也可以在对象死后释放所有内存。
答案 1 :(得分:0)
首先使用带有__strong
指针的id
毫无意义,ARC会尝试将release
,retain
等消息发送到指针,而不是每个你的对象(鉴于你当前的实现它甚至不知道你动态分配了多少个对象),所以,简而言之,无论有没有它都是一样的。至于泄漏,请尝试在alloc之前释放指针。
无论如何,正如其他人提到的,为什么不使用NSArray
或/和NSDictionary
?
修改以下评论:
当我说“无论有没有它都是一样的”我的意思是,它对你的记忆管理没有任何帮助,这是没有意义的。但是,您必须拥有所有权限定符,因此只需删除它就会出现错误(如您所报告的那样)。你应该使用
@property (nonatomic, assign) id __unsafe_unretained *array2;
至于你的记忆问题,你在free
之前尝试alloc
了吗?如果initWithCapacity:
被调用两次会发生什么,我知道你不会把它叫两次,但是不能保证仪器可以知道。
此外,here是您了解更好的ARC和所有限定符的规范。