繁体   English   中英

取消分配中的客观C过度释放

[英]objective-c over-releasing in dealloc

mystring是否过度发布?

-(void)dealloc {
    [mystring release];
    [mystring release];
    [super dealloc];
}

我假设这不会基于[nil release]不执行任何操作:

-(void)dealloc {
    [mystring release];
    mystring = nil;
    [mystring release];
    [super dealloc];
}

-编辑-假设我在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?
}

对于您的第一个示例,答案可能是!

通常,每个持有对另一个对象的引用的对象都应保留该对象直到完成,然后再调用一次一次发布,但是在某些异常(通常写得不好)的情况下,这可能不成立。 如果将对象保留x次,则需要将其释放x次,以及其他情况下内存管理不佳。 但是,最佳实践是,保留一个,释放一个,不要释放比保留更多的东西!

这样的过度释放有两个风险:

首先是如果第一个发布调用使mystring的引用计数等于0,它将被取消分配,然后您将一条消息发送到不再是有效对象的内存中。 Objective-C并非如此,它可能以多种方式做出反应,包括CRASHING。 发送消息到零,洁净,发送消息到已分配的东西,不是很多。

第二个是如果refcount不为零,则您释放了其他人的引用,因此在将来的某个时候,具有对mystring的引用的对象可能会认为该引用是有效的,并且不会因为引用是dealloc当引用计数在后续发布调用中达到零时。 与以前的错误相比,这将更难检测到,在先前的错误中,调试器将至少在堆栈帧跟踪中向您显示问题的实际区域。

您的第二个示例是正确的-向nil发送消息没有任何作用。 如果您担心会执行此类操作,请确保在释放后将变量设置为nil。

编辑:是的。 如果打算在一个以上的地方进行发布,那就应该这样做,但是根据应用程序的不同,您可能会考虑使用自动发布池。

这完全取决于您保留mystring的时间。 如果您有两个成员可能引用同一个对象并且都保留了该对象,则它们都应释放该对象。

因此,如果您使用mystring = [[somestring keep] keep],则您的第一个示例将是正确的;

第二个会更好。 因为释放时, 释放的是mystring指向的内存而不是mystring的内存。 因此, mystring不为null ,如果有人不小心使用了它, 您的应用程序将崩溃 这也取决于您的mystring保留了多少次

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM