复制对象时的内存管理

时间:2011-11-08 11:01:35

标签: objective-c memory-management copy retaincount

我知道我的问题已在StackOverflow上讨论过,但我发现答案不能完全满足我的需求。所以问题是:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

现在secondArray的保留计数是多少? 2还是1?我应该发布两次还是只发一次? copy或mutableCopy是否会增加COPYING(此事件中为secondArray)对象的保留计数?

2 个答案:

答案 0 :(得分:5)

你永远不应该关心绝对保留计数。只有你“平衡”,这意味着每个allocnew*copymutableCopyretain都需要相应的{{1} }或release(当不使用ARC时)。

如果您将此规则应用于每一行,您可以看到第二行有autorelease,但没有发布。事实上,在这里分配一个实例绝对没用,因为你无论如何都对它不感兴趣。所以它应该只是阅读:

alloc

但是,让我们讨论你的原始代码,看看发生了什么:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [firstArray mutableCopy];
// There is no third line.

在Objective-C中,我们经常谈到所有权:很少有方法可以让你成为对象的“拥有者”。这些是:

  • NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil]; NSMutableArray *secondArray = [[NSMutableArray alloc] init]; // secondArray points to a new instance of type NSMutableArray secondArray = [firstArray mutableCopy]; // You have copied another array (created a new NSMutableArray // instance) and have overwritten the pointer to the old array. // This means that the instance allocated in line 2 is still there // (was not released) but you don't have a pointer to it any more. // The array from line 2 has been leaked.
  • alloc,与new*
  • 一样
  • newFoocopy
  • mutableCopy

如果你打电话给这些,你会得到一个你负责的对象。这意味着您需要在这些对象上调用相应数量的retain和/或release。例如,如果您执行autorelease然后[[obj retain] retain];

,则可以

答案 1 :(得分:1)

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

发生的事情是您创建了内存泄漏。当您使用firstArray的mutableCopy用此行覆盖它时,您刚刚丢失了分配给secondArray的引用。

secondArray = [firstArray mutableCopy];

如果你然后释放secondArray两次,程序将崩溃,因为你过度释放由

分配的可变数组
secondArray = [firstArray mutableCopy];

您需要做的是确保您不会错误地覆盖保留的引用,并且余额与发布保持一致。