【问题标题】:iOS memory management questioniOS内存管理问题
【发布时间】:2026-01-18 23:50:01
【问题描述】:

我对围绕各种教程、文章、书籍等浮动的 setter 的内存管理示例有点困惑。这是一个典型的变体:

- (void) setOldAmount: (NSNumber*)newAmount 
{ 
  if (oldAmount != newAmount) {
     [oldAmount release];
     oldAmount = [newAmount retain]; 
  }
}


- (void) dealloc 
{ 
   [oldAmount release]; 
   [super dealloc]; 
}

oldAmount = [newAmount retain]; oldAmount 的-retain 消息,由-dealloc 中的-release 消息平衡;但是如果 newAmount 被发送 -retain 然后分配给 oldAmount,那么 newAmount 在哪里释放?这不是内存泄漏吗?

【问题讨论】:

    标签: objective-c ios memory-management


    【解决方案1】:

    newAmount 和 oldAmount 都是指向对象的指针。您通过指针保留和释放对象,但它是跟踪它被保留多少次的对象。指向同一个对象的两个变量可以互换使用。例如:

    NSNumber *a = [[NSNumber alloc] initWithInt:5];
    NSNumber *b = a;
    [b release];
    

    第三行的release平衡了第一行的alloc,因为a和b都指向同一个对象。

    在您的示例中也是如此。 newAmount 被保留,但 oldAmount 被分配指向同一个对象。下次调用 -setOldAmount:(或 -dealloc)时,将释放该对象。请注意:

    oldAmount = [newAmount retain];
    

    只是一个简写,意思是一样的:

    oldAmount = newAmount;
    [oldAmount retain];
    

    除了保留和分配以不同的顺序发生(这对结果没有任何影响)。

    了解这段代码中发生的事情很好,但是如果您将属性与合成访问器一起使用,则不必经常编写它。

    【讨论】:

      【解决方案2】:

      您必须从所有权的角度考虑 iPhone 内存管理。如果您拥有变量的所有权,则需要“保留”它。如果你保留一个对象,你需要释放它。所以你看不到的那段代码是调用 setOldAmount 的人。调用 setOldAmount 的人最有可能创建了 newAmount。当你分配一个变量时,它被隐式设置为在给你之前保留(否则它会在它到达你之前被释放,这很愚蠢)。当你不再关心它的价值时,释放它是你的工作。所以是的,如果调用 setOldAmount 的人从未释放 newAmount,则可能存在内存泄漏,但上面的代码是正确的。

      【讨论】: