为什么我的 UIViewController 在使用 initWithNibName 时会保留额外的时间?
我正在开发一个应用程序,它有一个主视图,希望在触摸按钮时生成一个子视图。因此,当我收到按钮事件时,MainViewController 通过调用 initWithNibName 并将 ChildViewController 存储在 ivar 中来生成子视图。然后,我通过附加动画并设置 childVC.view.hidden = NO 来显示 ChildView。
这是可行的,但我注意到关闭 ChildView 后 ChildViewController 永远不会被释放。我意识到当我第一次访问子视图时,ChildVC 的保留计数从 1 变为 2。因此,笔尖加载内部的某些内容似乎再次保留了我的 ChildVC(除了我在对象初始化期间期望的初始保留之外)。
有人可以帮我弄清楚为什么 ChildVC 会保留额外的时间,以及当我想关闭子视图时如何确保它完全释放?
编辑:这里有一些代码,只是稍微简化了。这些是父视图控制器上的方法。
-(IBAction)onLaunchChildButtonTouched:(id)sender
{
m_childViewController = [[ChildViewController alloc] initWithNibName:@"ChildViewController" bundle:nil];
[m_childViewController setParentDelegate:self]; // this is a weak reference
// m_childViewController retain count here is 1, as expected
m_childViewController.view.hidden = YES;
// m_childViewController retain count is now 2, not expected
[self.view addSubview:m_childViewController.view];
[self addTransitionEntrDir:YES]; // code omitted
m_childViewController.view.hidden = NO;
}
-(void)onChildWantsToClose:(id)child
{
NSAssert( child == m_childViewController, @"unexpected childVC" );
// if child view is now hidden, we should remove it.
if( m_childViewController != nil && m_childViewController.view.hidden )
{
[m_childViewController.view removeFromSuperview];
[m_childViewController release]; m_childViewController = nil;
// BUG: m_childViewController retain count is still 1 here, so it never gets released
}
}
I'm working on an app that has a Main view that wants to spawn a child view when a button is touched. So when I receive the button event, the MainViewController spawns the child view by calling initWithNibName and storing the ChildViewController in an ivar. I then show the ChildView by attaching an animation and setting childVC.view.hidden = NO.
This works, but I noticed that the ChildViewController was never getting released after closing the ChildView. I realized that the ChildVC's retain count went from 1 to 2 when I first access the child view. So something in the nib loading guts appears to be retaining my ChildVC again (in addition to the initial retain I expect during object initialization).
Can somebody help me figure out why the ChildVC is getting retained the extra time, and how can I make sure that it gets fully released when I want to close the child view?
Edit: here's some code, only slightly simplified. These are methods on the parent view controller.
-(IBAction)onLaunchChildButtonTouched:(id)sender
{
m_childViewController = [[ChildViewController alloc] initWithNibName:@"ChildViewController" bundle:nil];
[m_childViewController setParentDelegate:self]; // this is a weak reference
// m_childViewController retain count here is 1, as expected
m_childViewController.view.hidden = YES;
// m_childViewController retain count is now 2, not expected
[self.view addSubview:m_childViewController.view];
[self addTransitionEntrDir:YES]; // code omitted
m_childViewController.view.hidden = NO;
}
-(void)onChildWantsToClose:(id)child
{
NSAssert( child == m_childViewController, @"unexpected childVC" );
// if child view is now hidden, we should remove it.
if( m_childViewController != nil && m_childViewController.view.hidden )
{
[m_childViewController.view removeFromSuperview];
[m_childViewController release]; m_childViewController = nil;
// BUG: m_childViewController retain count is still 1 here, so it never gets released
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有代码,很难准确地说,但是您确定没有将您的
ChildVC
分配给其他对象的retain
属性吗?这可以解释您看到的意外的retain
。对于之前的回答,我很抱歉,我试图传达同样的信息,但我混淆了所有内容。
旧答案:请记住,UIViewController
的view
属性被保留:view控制器管理的视图。@property(nonatomic, keep) UIView *view所以,如果你像这样分配它:childVC.view = [[xxxxx alloc] initWithNibName:...];这解释了您所看到的内容。使用:childVC.view = [[[xxxxx alloc] initWithNibName:...] autorelease];Without code it is difficult to say exactly, but are you sure you are not assigning your
ChildVC
to aretain
property of some other object? This would explain the unexpectedretain
you see.Sorry for the previous answer, where I tried to convey this same message but I mixed everything up.
OLD ANSWER:keep in mind that theview
property of aUIViewController
is retained:viewThe view that the controller manages.@property(nonatomic, retain) UIView *viewso, if you assign to it like this:childVC.view = [[xxxxx alloc] initWithNibName:...];this explains what you are seeing.Use instead:childVC.view = [[[xxxxx alloc] initWithNibName:...] autorelease];我发现了问题,泄漏的 ChildViewController 正在实例化一个保留引用的对象。
有趣的是,我并不是简单地忘记发布这个参考资料。我确实有一个调用来释放它,但该代码从未运行,因为它假设 viewDidUnload 会运行并给我一个释放所有内容的机会,但它没有。我将 deinit 代码放入 dealloc 中,现在它可以工作了。
I found the problem, the leaky ChildViewController was instantiating an object that retained a ref back to it.
The interesting part is that I wasn't simply forgetting to release this reference. I did have a call to release it, but that code was never running because it assumed that viewDidUnload would run and give me a chance to release everything, but it didn't. I put me deinit code inside dealloc instead, and it works now.