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

发布于 2024-12-07 13:16:52 字数 1540 浏览 0 评论 0原文

我正在开发一个应用程序,它有一个主视图,希望在触摸按钮时生成一个子视图。因此,当我收到按钮事件时,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

画▽骨i 2024-12-14 13:16:52

如果没有代码,很难准确地说,但是您确定没有将您的 ChildVC 分配给其他对象的 retain 属性吗?这可以解释您看到的意外的 retain

对于之前的回答,我很抱歉,我试图传达同样的信息,但我混淆了所有内容。

旧答案:
请记住,UIViewControllerview 属性被保留:
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 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];

琴流音 2024-12-14 13:16:52

我发现了问题,泄漏的 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文