object-c 中的手动内存管理
manual memory-management in object-c
阅读本文时,我对 object-c 中的手动内存管理有疑问 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];
}
不知道自己的想法有没有错误,还请指教
你大部分是正确的,你的两个版本都很常见。
不过,中间代码段存在一个微妙的潜在问题。 newInventory
可能与 _inventory
不同,但释放 _inventory
仍会导致 newInventory
被释放。这是因为如果 newInventory
直接或间接地包含在 _inventory
.
中,那么唯一剩下的对 newInventory
的强引用可能是 _inventory
本身。
您还可以使用第三种形式来避免对临时变量的需要:
- (void)setInventory:(NSMutableArray *)newInventory {
[newInventory retain];
[_inventory release];
_inventory = newInventory;
}
最后,即使对于正确的内存管理来说并非绝对必要,您也可能有一些原因希望包括相等性检查。例如,尽管 Apple 努力使 -retain
和 -release
变快,但它们并不是免费的。因此,如果值没有真正发生变化,跳过它们可能仍然会提高效率。
此外,您可能希望在 setter 中进行其他工作,例如将视图标记为需要显示或使相关的缓存值无效。如果值没有真正改变,您可能希望避免这样做。
阅读本文时,我对 object-c 中的手动内存管理有疑问 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];
}
不知道自己的想法有没有错误,还请指教
你大部分是正确的,你的两个版本都很常见。
不过,中间代码段存在一个微妙的潜在问题。 newInventory
可能与 _inventory
不同,但释放 _inventory
仍会导致 newInventory
被释放。这是因为如果 newInventory
直接或间接地包含在 _inventory
.
newInventory
的强引用可能是 _inventory
本身。
您还可以使用第三种形式来避免对临时变量的需要:
- (void)setInventory:(NSMutableArray *)newInventory {
[newInventory retain];
[_inventory release];
_inventory = newInventory;
}
最后,即使对于正确的内存管理来说并非绝对必要,您也可能有一些原因希望包括相等性检查。例如,尽管 Apple 努力使 -retain
和 -release
变快,但它们并不是免费的。因此,如果值没有真正发生变化,跳过它们可能仍然会提高效率。
此外,您可能希望在 setter 中进行其他工作,例如将视图标记为需要显示或使相关的缓存值无效。如果值没有真正改变,您可能希望避免这样做。