为什么这会导致内存泄漏?

时间:2011-09-03 02:05:00

标签: iphone objective-c ios ipad

我是Objective-C的新手,我读过一些内存管理文章,但遇到了麻烦。

我有类似这样的课:

-(UIWebView*)getWebView{
    //UIWebView* webview = [UIWebView initWithFrame:self.frame];  edited,the original wrong line
    UIWebView* webview = [[UIWebView alloc] initWithFrame:self.frame]; 
    return webview; 
}
-(void)addToSelf{
    UIWebView* view = [self getWebView];
    [self addSubview:view];
    [view release];  //release here
}

在我看来,objc对象都像C指针(它是?) 并且这样想:

UIWebView* webview = [[UIWebView alloc] initWithFrame:self.frame];  //retain +1
UIWebView* view = [self getWebView];  //just a pointer to the same object ?
[self addSubview:view]; //retain +1
[view release];   //retain -1

现在查看retainCount = 1。 然后这个viewController将处理webview的生命周期。

我的想法一定有问题(肯定也是代码), 但我不知道为什么

UIWebView* webview = [[[UIWebView alloc] initWithFrame:self.frame] autorelease];

当我删除最后一个发布行时,代码工作正常,为什么? 有什么区别?

--------------编辑行---------------

几分钟前,有一个答案,但它消失了,现在我改写了我的想法:

答案是:

从方法返回对象时,我必须使用 autorelease 告诉编译器我已经结束它,然后使用addSubview,完成(不需要释放)。

我知道这是对的,但为什么它是对的?

在大多数代码中:

-(void)someMethod{
    UIWebView* webview = [[UIWebView alloc] initWithFrame:self.frame]; 
    [self addSubview:webview];
    [webview release];
}

这样可以正常工作,但是当将代码分成两个方法(如top)时,它就不是。

为什么我必须在返回对象时使用 autorelease

3 个答案:

答案 0 :(得分:4)

看起来好像你没有分配UIWebView:

UIWebView* webview = [[UIWebView alloc] initWithFrame:self.frame];

这意味着您可能没有有效的UIWebView,并且保留计数未定义,因为UIWebView的代码实际上使用了一些未知的内存。如果这样,你很幸运。

答案 1 :(得分:1)

您对保留和释放如何相互平衡的一般想法是正确的。当您删除最后一次保留呼叫时,您正在泄漏。除非您正在观察内存使用,否则这是一个不会引起注意的缺陷。 (泄漏在任何计算机上都很重要,但对手持设备的影响更大。)

实际上,如果方法创建(alloc)并返回一个对象,autorelease它。然后调用者可以使用该对象,而不用担心它的生命周期。

答案 2 :(得分:0)

*#1:'alloc'应该有责任在对象上调用release-statements。

#2:当您创建一个单独的方法来为您分配对象时,您不能拥有'release'语句,因为即使在call site方法使用它之前,它也会释放该对象。因此,我们调用autorelease而不是调用release,因此服从#1的主体,但仍然允许调用站点使用该对象。由于呼叫站点本身没有进行任何分配,因此它也不必担心任何版本。 ***