发布后将对象设置为nil - TT_RELEASE_SAFELY

时间:2011-05-12 02:17:11

标签: objective-c memory-management three20

我已经开始学习Three20了,我有一个关于TT_RELEASE_SAFELY的简单问题 到目前为止,我喜欢用这种方式编写代码:

UILabel *lab = [[UILabel alloc] initWithFrame:rect];
[self.view addSubview:lab];
[lab release];

在这里,我认为主池负责释放lab

的记忆

现在我发现TT_RELEASE_SAFELY的定义如下:

#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }

如您所见,在发布后,它将对象设置为nil

我想知道两种方式之间的区别,哪种方式更好。

感谢。

3 个答案:

答案 0 :(得分:6)

Sending a message to nil在Objective-C中有效。将消息发送到解除分配的对象不是。

向解除分配的对象发送消息:

id obj = [[MyClass alloc] init];
[obj release];
[obj doSomething]; // Crash!

向nil发送消息:

id obj = [[MyClass alloc] init];
[obj release], obj = nil;
[obj doSomething]; // Valid

在对象被释放后将nil赋值给变量是有争议的,因为它可以防止你意识到出现了问题。 Sedate Alien的例子:

[controlCenter dealloc];
...
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation];

由于已取消分配controlCenter,此代码将崩溃。结果,这个缺陷将被及早发现并修复。

[controlCenter dealloc], controlCenter = nil;
...
float timeLeft = [controlCenter timeToWaitBeforeBombDetonation];

此代码将0.0分配给timeLeft,即使controlCenter为零,它也似乎是一个有效的等待时间。


如果你正在编写一个Objective-C应用程序,那么你可能更关注通过避免崩溃来保持用户满意而不是破坏城市。如果后者是一个问题,你可能应该使用像Ada这样的类型安全的语言。

答案 1 :(得分:1)

我认为使用“安全版”的这些变体是一个明显糟糕的想法。

您的应用程序将以无声和神秘的方式失败,因为传递给nil的消息不会引发任何警告。最好不要将你的参考文献弄清楚,并利用NSZombieEnabled提供的所有功能。

答案 2 :(得分:0)

唯一的区别是TT_RELEASE_SAFELY在释放后将指针设置为nil,因此在发布后不会使用引用。该模式是一个很好的模式,TT_RELEASE_SAFELY宏使它更容易实现。