简体   繁体   English

为什么在使用initWithNibName时我的UIViewController会保留额外的时间?

[英]why does my UIViewController get retained an extra time when using initWithNibName?

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. 因此,当我收到button事件时,MainViewController通过调用initWithNibName并将ChildViewController存储在ivar中来生成子视图。 I then show the ChildView by attaching an animation and setting childVC.view.hidden = NO. 然后,我通过附加动画并设置childVC.view.hidden = NO来显示ChildView。

This works, but I noticed that the ChildViewController was never getting released after closing the ChildView. 这可行,但是我注意到关闭ChildView之后再也没有释放ChildViewController了。 I realized that the ChildVC's retain count went from 1 to 2 when I first access the child view. 我意识到,当我第一次访问子视图时,ChildVC的保留计数从1增加到2。 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). 因此,笔尖加载胆量中的某些内容似乎再次保留了我的ChildVC(除了我在对象初始化期间期望的初始保留之外)。

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? 有人可以帮我弄清楚为什么为什么要保留ChildVC多余的时间,并且当我要关闭子视图时,如何确保完全释放它?

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

    }
}

Without code it is difficult to say exactly, but are you sure you are not assigning your ChildVC to a retain property of some other object? 如果没有代码是很难说究竟,但是你确定你是不是你的分配ChildVCretain一些其他对象的属性? This would explain the unexpected retain you see. 这将解释您看到的意外retain

Sorry for the previous answer, where I tried to convey this same message but I mixed everything up. 抱歉,上一个答案是我试图传达相同的信息,但我将所有内容混在一起。

OLD ANSWER: 旧答案: keep in mind that the view property of a UIViewController is retained: 请记住,保留了UIViewControllerview属性: view 视图

The view that the controller manages. 控制器管理的视图。

@property(nonatomic, retain) UIView *view @property(非原子的,保留)UIView * view so, if you assign to it like this: 因此,如果您这样分配它: childVC.view = [[xxxxx alloc] initWithNibName:...]; childVC.view = [[xxxxx分配] initWithNibName:...]; this explains what you are seeing. 这解释了您所看到的。 Use instead: 改用: childVC.view = [[[xxxxx alloc] initWithNibName:...] autorelease]; childVC.view = [[[[xxxxx alloc] initWithNibName:...]自动释放];

I found the problem, the leaky ChildViewController was instantiating an object that retained a ref back to it. 我发现了问题,泄漏的ChildViewController正在实例化一个保留引用的对象。

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. 我确实有一个释放它的调用,但是该代码从未运行过,因为它假定viewDidUnload将运行并为我提供了释放所有内容的机会,但是没有。 I put me deinit code inside dealloc instead, and it works now. 我将deinit代码放到了dealloc中,现在可以使用了。

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

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