【问题标题】:will reassign a pointer cause memory leak?重新分配指针会导致内存泄漏吗?
【发布时间】:2012-08-10 21:52:36
【问题描述】:

我有以下代码,想知道当 iOS 重新收集分配的内存时会发生什么。 p1 指向的内存是否会在之后自动释放,尽管它​​现在指向不同的内存?而且 p2 指向的内存也会被自动释放,因为 p1 在语义上意味着在开始时指向自动释放的内存?

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
NSMutableArray *p2 = [[NSMutableArray alloc] init];

// what will happen to the memory p1 and p2 point to
// after the following assignment, and at later stage?
p1 = p2;

【问题讨论】:

  • 具有托管内存的语言通常不会出现内存泄漏。
  • 重读您的问题,您实际上是在询问p1 的初始设置的autorelease 性质是否是变量p1 或其指向的对象的函数。是后者;获取retainCountautorelease 等的是对象本身。变量p1p2 仅仅是指向对象的指针。当你设置p1 = p2时,它不会改变p2指向的对象的+1retainCount,也不会使它成为autorelease对象。
  • 正确。所以 p1 最初指向的对象的性质仍然是自动释放的,因此它会在适当的时候由操作系统自动释放,对吗?

标签: ios memory-management memory-leaks autorelease


【解决方案1】:

顺便说一句,如果您将来有类似的问题,可以通过 (a) 对相关类进行子类化来轻松测试; (b) 添加您自己的 dealloc 来记录释放。例如:

@interface TestNSMutableArray : NSMutableArray
@end

@implementation TestNSMutableArray
- (void)dealloc
{
    [super dealloc]; // only needed for non-ARC
    NSLog("%s", __FUNCTION__);
}
@end

然后使用TestNSMutableArray 而不是NSMutableArray 尝试您的代码。如果你看到你的dealloc,你很好。如果没有,你就是在泄漏。

显然您也可以使用 Instruments,但当我第一次接触 Objective-C 内存处理时,我发现这是一种简单但有用的诊断技术。

【讨论】:

    【解决方案2】:
    NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
    NSMutableArray *p2 = [[NSMutableArray alloc] init];
    
    // what will happen to the memory p1 and p2 point to
    // after the following assignment, and at later stage?
    p1 = p2;
    

    “iOS 正在回收分配的内存” - iOS 从来没有垃圾收集功能。

    p1 是指向自动释放对象的指针。

    p2 是指向非自动释放对象的指针(您或 ARC 必须稍后释放它以避免内存泄漏)

    在 p1 = p2 之后,p1 指向 p2 指向的非自动释放对象。 p1 指向的原始对象此时是孤立的。

    如果您使用 ARC 功能,则无需执行任何操作。在手动内存管理环境下,您可以使用[p2 release];[p1 release]; 来平衡释放您拥有的已分配对象。

    【讨论】:

      【解决方案3】:

      在 ARC 下,您无需执行任何操作 两个对象都会被释放。 ARC之外:

      NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
      

      返回一个自动释放的值。你不需要释放这个值。但是,这个:

      NSMutableArray *p2 = [[NSMutableArray alloc] init];
      

      手动保留计数为 1。完成后,您需要释放 p2 的值(然后将其分配给 p1)。

      【讨论】:

        【解决方案4】:

        什么都不会泄露,p1 是一个自动释放的对象,在那种情况下,将 p2 分配给 p1 后,它们都只是指向同一个对象。 p1 指向的原始对象由自动释放池管理,当池耗尽时将被释放。 ARC与否,假设您稍后发布p2,则不会泄漏。

        【讨论】:

          【解决方案5】:

          首先,这取决于您是否使用 ARC。

          使用 ARC: 不会有内存泄漏。操作系统将释放 p1 的内存,数组现在将指向与 p2 相同的位置。然后,操作系统会在 p1 和 p2 消失时(例如释放类时)释放两个数组的内存。

          无 ARC: p1 将被泄露。要修复泄漏,您需要

          [p1 release];
          

          在将 p2 的值赋给 p1 之前。如果在释放类之前没有对这两个数组调用 release,p2 的内存也会泄漏。

          【讨论】:

          • 在 ARC 之外,p1 的初始值不会被泄露,因为它是一个自动释放的值。将 p2 分配给 p1 时,p1 现在有一个需要释放的保留值。但是,p1 之前的值不会泄露,会在 runloop 返回时释放。
          猜你喜欢
          • 2023-03-06
          • 2021-06-14
          • 1970-01-01
          • 1970-01-01
          • 2021-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多