问题描述
|
如果我有一个对象,例如NSIndexPath,该怎么办?在我执行复制操作之前,我总是先释放该对象吗?
内存计数是否可以小于0?
我这样做是为了防止内存泄漏..这是一个好方法吗?
// global之前已经有一些值,或者它没有任何值..我想更新
//使用一个新值(我不再关心旧指针)
[global release]
global = [indexPath copy];
解决方法
别。当保留计数达到0时,您的对象将被取消分配并且其指针将变为无效,因此再次使用该对象将导致不可预测的结果(即崩溃)。
您应该通读Apple的《内存管理指南》。
这是基本规则:
您只释放或拥有自己的对象。如果使用名称以“ alloc”,“ new”,“ copy”或“ mutableCopy”开头的方法(例如alloc,newObject或mutableCopy)创建对象,或者发送该对象,则您拥有该对象的所有权保留消息。
您使用释放或自动释放来放弃对象的所有权。自动释放仅表示“将来发送释放消息”(特别是:使用的自动释放池收到耗尽消息时)。
更新:
正如Josh所指出的,您需要考虑的一种情况是global和indexPath相同时。在那种情况下,您仍将“需要”指针(以执行复制),因此您可以自动释放(而不是释放)或使用临时变量来处理该指针。
, 只要
global
具有您不再需要的旧值或为nil
,您所做的就本质上是正确的。如果它是类的ivar之一,则在创建该类的实例时将为“ 2”。一个问题是,如果新的indexPath
正好与已经在ѭ1already中的对象相同,则您将释放过多的对象,并且将崩溃。
// 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
是否相同,如果不相同,则不进行任何操作,这样可能会稍微好一些。