开发者

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

开发者 https://www.devze.com 2023-04-10 14:27 出处:网络
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 initW

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

    }
}


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? This would explain the unexpected retain 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 the view property of a UIViewController is retained: view

The view that the controller manages.

@property(nonatomic, retain) UIView *view so, 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];


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号