繁体   English   中英

如何使用内部包含NSNumber对象的NSMutableArray成员的对象正确释放NSMutableArray?

[英]How to properly release a NSMutableArray with objects that have a NSMutableArray member with NSNumber objects inside?

我对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];

运行此代码会泄漏内存,Instruments显示泄漏的内存是在以下行分配的:

cop.others = [others mutableCopy];

我做错了什么?

您正在创建一个副本:您拥有但忘记发布的[others mutableCopy] 该行应为:

cop.others = [[others mutableCopy] autorelease];

如果让container数组成为Tester对象的唯一所有者,则测试代码将更加清晰:

NSMutableArray* container = [[NSMutableArray alloc] init];
Tester* orig = [[Tester alloc] init];
for (int i = 0; i < 10000; ++i)
    [container addObject:[[orig copy] autorelease]];

while([container count] > 0)
    [container removeLastObject];

[container release];

现在,您可以删除清空容器的循环。

或者您可以跳过容器:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

Tester* orig = [[[Tester alloc] init] autorelease];
for (int i = 0; i < 10000; ++i)
    [[orig copy] autorelease];

[pool drain]; // At this point all Tester objects are released
cop.others = [others mutableCopy]

其他被声明为保留财产,因此将其分配给新价值即可建立所有权声明。 -mutableCopy是一种隐含所有权的方法(因为它包含单词“ copy”)。 因此,您现在有两个所有权要求,必须将两者都释放。 推荐的方法是首先将副本分配给temp变量,然后将其分配给属性并释放它,如下所示:

NSMutableArray *tmpArray = [others mutableCopy];
cop.others = tmpArray;
[tmpArray release];

您也可以一步一步地执行此操作,避免使用temp对象,尽管这样做会使用自动释放池,因此效率会稍低一些:

cop.others = [[others mutableCopy] autorelease];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM