泄漏视图和其他对象

时间:2011-05-15 10:12:15

标签: objective-c ios memory-management uiview uiviewcontroller

我总是发现这令人困惑。有人可以帮我解释一下吗?

在视图控制器类中,我有一个滚动视图,我想为它添加一些视图。因此,我在视图控制器中创建了一个帮助方法,该方法创建视图并将其返回给调用者。调用者又将此新视图添加到滚动视图。

所以我在这里调用方法来获取视图并将其直接传递给addSubView:

[scrollView addSubView:[self getView]];

以下是创建视图的方法:

-(UIView *)getView {

   UIView *v = [[UIView alloc] init];

   // do all the guff I need to configure the view

   return v;
}

问题是v何时或何地被释放?我应该在autorelease创建getView时将其指定为addSubView:,还是在调用{{1}}后将其释放?感谢。

2 个答案:

答案 0 :(得分:2)

由于-[UIView addSubview:]通过向其发送-retain消息来获取传入视图的所有权,因此您应该发送getView一条-autorelease消息的返回值:< / p>

return [v autorelease];

答案 1 :(得分:0)

雅各布的结论是正确的,但他的理由是错误的,或者至少不清楚(我试过但未能将其纳入评论)。

getSubview:中,您创建了一个对象。您现在是所有者*。当方法结束时,您必须释放对象,放弃您的所有权,否则它将泄漏。您从方法返回对象的事实对此规则没有任何影响。

在这种情况下,由于您希望调用此方法的代码能够使用该对象执行某事,因此您使用autorelease,说“我放弃了我的所有权,但不要实际上,除非调用代码有机会查看是否要提出声明,否则不要删除此对象。另一端发生的事情(保留,复制,立即发布,任何事情)与getSubview:中的代码无关。所有这些方法都需要担心它拥有的内存。否则,即依赖于调用代码将对内存执行特定操作的事实,将导致错误。

稍微更技术性的术语,v指向的对象必须被释放或自动释放,因为v将在方法结束时超出范围。一旦名称超出范围,您就不能再使用该名称来引用对象,并且如果该名称是您对该对象的唯一引用,则表示您已泄露。


*请注意,一个对象可以拥有多个所有者 - retain它成为部分所有者的任何其他对象。