简体   繁体   English

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

[英]Why does this cause memory leaks?

I'm new to Objective-C, and I've read some memory management articles but am having trouble. 我是Objective-C的新手,虽然我读过一些内存管理文章,但是遇到了麻烦。

I hava a class something like this: 我上课是这样的:

-(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
}

In my thought, objc objects are all like C pointers (it is ?) And thinking like this: 在我看来,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

Now view's retainCount = 1 . 现在查看的retainCount = 1 Then this viewController will handle the webview's life cycle. 然后,此viewController将处理Webview的生命周期。

There must be something wrong with my thought (sure also the code), but I don't know why . 我的想法一定有问题(还请确保代码), 但是我不知道为什么

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

When I remove the last release line, code works fine, why? 当我删除最后一个发布行时,代码可以正常工作,为什么? What's the difference? 有什么不同?

--------------edit line--------------- --------------编辑行---------------

Few minutes ago , there's an answer about it but it's disappeared , now I rewrite my thought: 几分钟前,有一个答案,但是它消失了,现在我重写了自己的想法:

The answer says: 答案是:

When returning object from method , i must use autorelease to tell compiler I have end with it, and then using addSubview , finish (no need releasing). 从method返回对象时,我必须使用autorelease告诉编译器我已经结束了,然后使用addSubview结束(不需要释放)。

I know this is right , but why it's right ? 我知道这是对的,但为什么会这样呢?

In most of codes: 在大多数代码中:

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

this works fine, but when separate the code to two methods like the top ,it's not. 这可以正常工作,但是当将代码分离到两个方法(例如top)时,事实并非如此。

Why i must use autorelease when returning object? 为什么返回对象时必须使用自动释放

It looks as if you don't alloc the UIWebView: 似乎您没有分配UIWebView:

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

That means you probably don't have a valid UIWebView, and a retain count that is undefined, since the code for UIWebView is actually using some unknown piece of memory. 这意味着您可能没有有效的UIWebView,并且保留计数未定义,因为UIWebView的代码实际上正在使用一些未知的内存。 If this works, you are lucky. 如果这有效,那么您很幸运。

Your general idea of how retains and releases balance each other is correct. 您关于如何保持和释放平衡的一般想法是正确的。 When you remove that last retain call, you are leaking. 删除最后一个保留呼叫时,您正在泄漏。 This is a defect that won't be noticeable unless you're observing memory use. 除非您正在观察内存使用情况,否则这是一个不会明显的缺陷。 (Leaks are important on any computer, but have a greater impact on handheld devices.) (泄漏在任何计算机上都很重要,但对手持设备的影响更大。)

In practice, if a method creates ( alloc ) and returns an object, autorelease it. 实际上,如果方法创建( alloc )并返回一个对象,请autorelease它。 The caller can then just use that object, and not worry about its lifetime. 然后,调用者可以只使用该对象,而不必担心其寿命。

*#1: Method that 'alloc's should have the responsibility to call the release-statements on the object. *#1:“ alloc”的方法应负责在对象上调用释放语句。

#2: When you create a separate method to alloc an object for you, you cannot have 'release' statement, since that will release the object even before call site method uses it. #2:当您创建单独的方法来为您分配对象时,您将无法使用“释放”语句,因为即使在调用站点方法使用它之前,该语句也会释放该对象。 Hence, instead of calling release we call autorelease and thus obeying the principal of #1, but still allowing call-site to use the object. 因此,不是调用release,而是调用autorelease,因此遵循#1的原则,但仍允许调用站点使用该对象。 As call-site didn't do any alloc by itself, it also does not have to worry about any releases. 由于呼叫站点本身并不执行任何分配,因此它也不必担心任何发布。 *** ***

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

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