释放变量的影响大于保留计数

时间:2012-02-17 00:26:02

标签: iphone objective-c ios cocoa-touch

我有一个实例变量声明为保留属性&然后我发布了2次。释放后我没有使用它。这不会导致任何崩溃。是否有任何其他影响释放变量超过需要(假设变量在发布后不会被使用):

@property (nonatomic, retain) NSString *myVariable;
self.myVariable = nil;
self.myVariable = nil;

5 个答案:

答案 0 :(得分:4)

事实上,你不是两次释放它。这是因为你正在使用属性。第一次调用self.myVariable = nil时,您将释放它(假设它有一个值)。但第二次,它已经没有了,所以没有什么可以发布的。

一般来说,实际上多次释放一个对象(或者更准确地说,发布的版本多于保留版本)非常糟糕,并且几乎肯定会使您的应用程序崩溃。

答案 1 :(得分:2)

你实际上并没有发布两次。鉴于setter看起来像这样:

- (void)setMyVariable:(NSString)value
{
    [myVariable release];
    myVariable = [value retain];
}

第一个self.myVariable = nil将释放myVariable iVar,并且还会将其设置为nil。下一个self.myVariable = nil将不执行任何操作,因为[nil release]不执行任何操作。

实际上,过度释放对象会(通常)导致崩溃。

答案 2 :(得分:1)

您可能会对变量和对象之间的区别感到困惑。单个变量可以与释放无限次使用(例如,如果为nil,或者在每次释放之前它保存完全不同的保留对象,等等。这是因为变量不能保存任何对象,或者不同的对象保持不同次)。在您的示例中,变量在第二次发布期间不保留任何对象(nil)。

但释放任何一个非零对象只是一次太多可能是导致崩溃的原因。

答案 3 :(得分:0)

您的代码中不会发生任何事情。我假设您正在使用ARC(自动引用计数),因此您通过将其指针设置为nil来“释放”它。

它是如何工作的,假设你在内存中分配了一个NSString对象,你创建它并为它指定一个指针。

所以现在你的指针指向那个对象,它的作用是:如果一个对象不再有一个指向它的指针,那么它会自动释放。假设你只有那个NSString上的“myvariable”指针,那么当你将它设置为nil时它就会被释放。

如果你再次将myvariable设置为nil,那么你绝对没有做任何事情,因为之前已经发布了该对象。

请注意,这意味着如果你有另一个变量也指向那个NSString,那么对象WONT将被释放,但myvariable将不再指向它。

我忘了提及,你可以在Ray Wenderlich的“iOS 5 by tutorials”中找到关于arc如何工作的优秀解释。

PD:如果您使用ARC,则应更改

@property(nonatomic,retain)NSString * myVariable;

@property(非原子,强)NSString * myVariable;

答案 4 :(得分:0)

使用iOS 5中的新ARC(自动引用计数),你不必担心这个问题,因为编译器会处理这个问题。

在此处了解详情: http://clang.llvm.org/docs/AutomaticReferenceCounting.html

但是,如果你不能/不想使用ARC,这是我的替代答案:

通过你正在进行的方式访问vars(self.var = nil),我的猜测是这些合成函数负责不释放非保留var,所以你可以安全地这样做多次你喜欢(虽然不是很优雅)。

另一方面,如果你明确地调用像[var release]这样的版本两次或更多次,你可能会遇到非常讨厌的问题。