【问题标题】:Memory management while copying objects复制对象时的内存管理
【发布时间】:2011-12-24 08:43:20
【问题描述】:

我知道我的问题已经在 StackOverflow 上讨论过,但我发现答案不完整,无法满足我的需要。所以问题是:

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

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

【问题讨论】:

    标签: objective-c memory-management copy retaincount


    【解决方案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];
    

    您需要做的是确保您不会错误地覆盖保留的引用,并在发布时保持平衡。

    【讨论】:

      【解决方案2】:

      您永远不应该关心绝对保留计数。只是你是“平衡的”,这意味着对于每个allocnew*copymutableCopyretain,你需要一个对应的releaseautorelease(当不使用 ARC 时,是)。

      如果您将此规则应用于每一行,您可以看到您的第二行有一个alloc,但没有释放。事实上,在这里分配一个实例是绝对没用的,因为你反正对它不感兴趣。所以它应该简单地阅读:

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

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

      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.
      

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

      • alloc
      • new*,如newFoo
      • copymutableCopy
      • retain

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

      【讨论】:

      • 我要补充一点,您有两个拥有的对象,需要在某个阶段释放。你是对的 - retainCount 并不重要 - 只需担心平衡拥有呼叫和释放呼叫。
      • 实际上 secondArray 已经在代码中很远的地方分配并使用了。为了方便,我把它写在第二行。因此,如果我说得对,以避免内存泄漏,我应该首先释放 secondArray,这绝对有效?
      • @AndreyChernukha:你只有在完成后才释放secondArray 指向的对象。 release 表示:从这行开始,我不再需要那个对象了;它可能会被释放。 autorelease 表示:很快,我就不再需要它了;但它应该至少在我离开这个方法之前保持活力。(这不是 100% 正确,但足够接近真相以提供有用的信息)
      猜你喜欢
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      相关资源
      最近更新 更多