我是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 ?
答案 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的主体,但仍然允许调用站点使用该对象。由于呼叫站点本身没有进行任何分配,因此它也不必担心任何版本。 ***