如果我有一个对象怎么办,比如NSIndexPath,在我复制之前我总是首先发布它?
内存数是否可以低于0? 我这样做是为了防止内存泄漏..这是一个好方法吗?
// global在此之前已经有了一些值,或者它没有值..我想更新
//这带有一个新值(我不再关心旧指针)
[global release]
global = [indexPath copy];
答案 0 :(得分:8)
别。当保留计数达到0时,您的对象将被释放并且其指针将变为无效,因此再次使用它将导致不可预测的结果(即崩溃)。
您应该阅读Apple的Memory Management Guide。
这是基本规则:
<强>更新强>
正如Josh所指出的,你需要考虑的一个案例是global和indexPath是相同的。在这种情况下,您仍然“需要”指针(执行复制),因此您要么自动释放(而不是释放),要么使用临时变量来处理它。
答案 1 :(得分:0)
您所做的事情基本上是正确的,只要global
具有您不再需要的旧值或nil
。如果它是类的ivars之一,则在创建类的实例时它将为nil
。唯一的问题是,如果新的indexPath
碰巧与global
中已经存在的对象相同,那么您将会过度释放并且会崩溃。
// global points to object at 0x8BADFOOD
// indexPath also happens to be 0x8BADFOOD; for some reason, it
// hasn't changed since last time. This _can_ happen.
[global release]; // object at 0x8BADFOOD is deallocated
global = [indexPath copy]; // indexPath no longer valid!
// Crash! Bang! Boom!
避免这种情况的方法是使用临时变量。
当您将属性声明为copy
并合成该属性时,创建的setter方法看起来与此类似,您可以执行相同的操作:
- (void)setMyFloozit:(Floozit *)newFloozit {
// Copy first in case newFloozit and myFloozit are for
// some reason the same object
// Take ownership of a copy of newFloozit
Floozit * tmp = [newFloozit copy];
// We no longer need old value of myFloozit, so we release it.
[myFloozit release];
// tmp contains a value that we own, we just need to assign
// it to the correct name.
myFloozit = tmp;
}
通过首先检查newFloozit
和myFloozit
是否相同,如果它们无效,可以稍微改善一点。