object-c 中的手动内存管理
Posted
技术标签:
【中文标题】object-c 中的手动内存管理【英文标题】:manual memory-management in object-c 【发布时间】:2015-04-07 07:46:04 【问题描述】:当我阅读guide 时,我对 有疑问。
为了让问题更清楚,我在下面粘贴了让我感到困惑的代码:
// 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];
我不确定我的想法是否有一些错误,所以请帮帮我。
【问题讨论】:
【参考方案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 中进行其他工作,例如将视图标记为需要显示或使相关的缓存值无效。如果值没有真正改变,您可能希望避免这样做。
【讨论】:
以上是关于object-c 中的手动内存管理的主要内容,如果未能解决你的问题,请参考以下文章
iphone(object-c) 内存管理 有效的内存管理 后半部分