mystring是否被过度释放?
-(void)dealloc {
[mystring release];
[mystring release];
[super dealloc];
}
我认为这不会基于[nil release]不做任何事情:
-(void)dealloc {
[mystring release];
mystring = nil;
[mystring release];
[super dealloc];
}
CNC中 假设我在init中分配mystring并在doSomething中释放它:
-(id)init {
if (self = [super init]) {
mystring = [[NSString string] retain];
}
return self;
}
-(void)doSomething {
[mystring release]; // for some good reason
// ...etc
}
现在为了避免基于我上面的例子在dealloc中过度释放,我是否必须在doSomething方法中明确地执行此操作?
-(void)doSomething {
[mystring release];
mystring = nil; // <- is this mandatory to avoid over-releasing in dealloc?
}
最大的问题是,当我在类中的其他地方发布它时,我必须明确地将它设置为nil,以避免在dealloc中过度释放吗?
如果我在doSomething中明确设置为nil,那么我可以在dealloc中执行尽可能多的发布吗?
-(void)dealloc {
[mystring release];
[mystring release]; // <- does nothing because mystring explicitly nil?
}
答案 0 :(得分:1)
对于你的第一个例子,答案可能是!
通常,每个持有对另一个对象的引用的对象应该保留它直到它们完成,然后调用一次释放,但是在一些非常奇特的(并且通常写得不好)的情况下,这可能不成立。如果将对象保留x次,则需要释放x次,以及其他内存管理不良的情况。但是最佳实践,是的,一个保留,一个发布,不会释放超过你保留的数量!
过度释放有两种风险:
第一个是如果第一个释放调用使得mystring的引用计数等于0,它将被释放,然后你将一条消息发送到一块不再是有效对象的内存。 Objective-C并不是真的喜欢这个,并且可能以各种方式做出反应,包括CRASHING。发送消息给nil,kosher,消息到dealloc'd,而不是那么多。
第二个是如果引用计数不为零,你刚刚发布了别人的引用,所以在将来的某个时候,一个引用mystring的对象可能会认为引用是有效的,它不会是因为当refcount在随后的释放调用中达到零时,它被释放。这比前一个错误更难检测,其中调试器至少会向您显示问题源自堆栈帧跟踪的实际区域。
你的第二个例子是正确的 - 向nil发送消息什么都不做。如果你担心你会做这样的事情,请确保在释放后将变量设置为nil。
编辑:是的。如果您打算在多个地方发布,那么您应该这样做,但是根据应用程序的不同,您可以考虑使用自动发布池。答案 1 :(得分:0)
这一切都取决于你保留mystring的时间。如果你有两个成员可以引用同一个对象并且都保留对象,那么它们都应该释放该对象。
所以如果你使用mystring = [[somestring retain] retain],你的第一个例子就是正确的;
答案 2 :(得分:0)
第二个会更好。因为当你释放时,你释放mystring指向的内存而不是mystring的内存。因此, mystring不为空,如果有人意外使用它,您的应用将崩溃。它还取决于你的mystring被保留多少次