如何正确释放带有 NSMutableArray 成员且内部有 NSNumber 对象的对象的 NSMutableArray?
我对 iOS 内存管理感到困惑。我有一个类,它有一个 NSMutableArray 类型的成员。当将这种类型的对象存储在另一个数组中并删除它们时,Instruments 显示所有这些成员都会泄漏内存。这是我的流氓类的定义:
@interface Tester : NSObject {
int some;
NSMutableArray* others;
}
@property int some;
@property (nonatomic, retain) NSMutableArray* others;
-(id)init;
-(id)copy;
-(void)dealloc;
@end
这是流氓类的实现:
@implementation Tester
@synthesize some;
@synthesize others;
-(id)init {
self = [super init];
if(self) {
some = 0;
others = [[NSMutableArray alloc] initWithCapacity:5];
int i;
for(i = 0; i < 5; ++i) {
[others addObject:[NSNumber numberWithInt:i]];
}
}
return self;
}
-(id)copy {
Tester* cop = [[Tester alloc] init];
cop.some = some;
cop.others = [others mutableCopy]
return cop;
}
-(void)dealloc {
[others removeAllObjects];
[others release];
[super dealloc];
}
@end
这是我测试它的方法:
NSMutableArray* container = [[NSMutableArray alloc] init];
Tester* orig = [[Tester alloc] init];
int i;
for(i = 0; i < 10000; ++i) {
Tester* cop = [orig copy];
[container addObject:cop];
}
while([container count] > 0) {
[[container lastObject] release];
[container removeLastObject];
}
[container release];
运行此代码会泄漏内存,仪器显示泄漏的内存是在以下行分配的:
cop.others = [others mutableCopy];
我做错了什么?
I'm puzzled about iOS memory management. I have a class that has a member of type NSMutableArray. When storing objects of this type in another array and removing them, Instruments shows that all those members leak memory. Here's the definition of my rogue class:
@interface Tester : NSObject {
int some;
NSMutableArray* others;
}
@property int some;
@property (nonatomic, retain) NSMutableArray* others;
-(id)init;
-(id)copy;
-(void)dealloc;
@end
Here's the implementation of the rogue class:
@implementation Tester
@synthesize some;
@synthesize others;
-(id)init {
self = [super init];
if(self) {
some = 0;
others = [[NSMutableArray alloc] initWithCapacity:5];
int i;
for(i = 0; i < 5; ++i) {
[others addObject:[NSNumber numberWithInt:i]];
}
}
return self;
}
-(id)copy {
Tester* cop = [[Tester alloc] init];
cop.some = some;
cop.others = [others mutableCopy]
return cop;
}
-(void)dealloc {
[others removeAllObjects];
[others release];
[super dealloc];
}
@end
And here's how I test it:
NSMutableArray* container = [[NSMutableArray alloc] init];
Tester* orig = [[Tester alloc] init];
int i;
for(i = 0; i < 10000; ++i) {
Tester* cop = [orig copy];
[container addObject:cop];
}
while([container count] > 0) {
[[container lastObject] release];
[container removeLastObject];
}
[container release];
Running this code leaks memory and Instruments shows that the leaked memory is allocated at line:
cop.others = [others mutableCopy];
What have I done wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在创建一个副本:
[others mutableCopy]
,您拥有该副本但忘记释放。该行应该是:如果您让
container
数组成为Tester
对象的唯一所有者,则测试代码会更清晰:现在您可以删除清空的循环容器。
或者你可以跳过容器:
You are creating a copy:
[others mutableCopy]
which you own but forget to release. The line should be:You testing code would be clearer if you'd let the
container
array be the sole owner of theTester
objects:Now you could remove the loop that empties the container.
Or you could just skip the container:
其他的被声明为保留财产,因此分配给它会建立对新价值的所有权主张。 -mutableCopy 是一种暗示所有权的方法(因为它包含“复制”一词)。因此,您现在有两个所有权主张,两者都必须被释放。建议的方法是首先将副本分配给临时变量,然后将其分配给您的属性并释放它,如下所示:
您也可以一步完成此操作,避免临时对象,尽管这样做使用自动释放池,效率稍低,因为:
Others is declared as a retained property, so assigning to it establishes an ownership claim on the new value. -mutableCopy is a method that implies ownership (because it contains the word "copy"). So you now have two claims of ownership, both of which must be released. The recommended way to do this is to assign the copy first to a temp variable, then assign that to your property and release it, like so:
You could also do this in one step, avoiding the temp object, although doing so uses the autorelease pool and is slightly less efficient because of that: