【问题标题】:manual memory-management in object-cobject-c 中的手动内存管理
【发布时间】:2015-04-07 07:46:04
【问题描述】:

当我阅读guide 时,我对 object-c 中的手动内存管理有疑问。

为了让问题更清楚,我在下面粘贴了让我感到困惑的代码:

// CarStore.m
- (void)setInventory:(NSMutableArray *)newInventory {
    if (_inventory == newInventory) {
        return;
    }
    NSMutableArray *oldValue = _inventory;
    _inventory = [newInventory retain];
    [oldValue release];
}

我认为上面的代码做了重复操作:

// CarStore.m
- (void)setInventory:(NSMutableArray *)newInventory {
    // if we can ensure '_inventory' is different with 'newInventory'
    if (_inventory == newInventory) {
        return;
    }

    // we can release '_inventory' firstly and safely
    [_inventory release];
    _inventory = [newInventory retain];
}

还有

// CarStore.m
- (void)setInventory:(NSMutableArray *)newInventory {
    // if we don't check the equal between '_inventory' and 'newInventory' firstly
    // then we need temp '_inventory', since '_inventory' and 'newInventory' maybe the same object
    NSMutableArray *oldValue = _inventory;
    _inventory = [newInventory retain];
    [oldValue release];
}

我不确定我的想法是否有一些错误,所以请帮帮我。

【问题讨论】:

    标签: objective-c properties release retain reference-counting


    【解决方案1】:

    您基本上是正确的,并且您的任何一个版本都很常见。

    不过,中间的 sn-p 存在一个微妙的潜在问题。 newInventory 可能与 _inventory 不同,但释放 _inventory 仍将导致 newInventory 被释放。这是因为如果newInventory 直接或间接包含在_inventory 中,那么对newInventory 的唯一剩余强引用可能是_inventory 本身。

    您还可以使用第三种形式来避免需要临时变量:

    - (void)setInventory:(NSMutableArray *)newInventory {
        [newInventory retain];
        [_inventory release];
        _inventory = newInventory;
    }
    

    最后,您可能希望包含相等性检查,即使这对于正确的内存管理并不是绝对必要的。例如,尽管 Apple 努力使 -retain-release 快速,但它们并不是免费的。因此,如果值没有真正改变,跳过它们可能仍然是一种效率改进。

    此外,您可能希望在 setter 中进行其他工作,例如将视图标记为需要显示或使相关的缓存值无效。如果值没有真正改变,您可能希望避免这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-10
      • 2011-05-04
      • 2014-07-29
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      相关资源
      最近更新 更多