解散后未释放 UIViewController 子类

UIViewController subclass not being released after dismiss

所以我 运行 解决了一个似乎已经在这里一次又一次解决的问题。不幸的是,我无计可施,所以我会 post 看看是否有人可以提供帮助。

如标题所示,我遇到了内存泄漏(无限内存增长)。我可以在 Instruments (Allocations) 中看到我的 InspectionPageTableViewController object 正在分配,但从未解除分配 - 有一个 malloc,但没有相应的空闲。问题是,我看不出这是怎么回事。 object 的整个历史看起来像这样(从实例化视图控制器到它被解雇):

此事件的堆栈跟踪如下所示:

相关方法的代码(在 InspectionViewController 中)是这样的:

- (void)loadScrollViewWithPage:(NSUInteger)page
{
    NSUInteger numberOfPages = self.titleView.numberOfPages;
    //self.navigationItem.rightBarButtonItem.enabled = page == numberOfPages;

    if (page >= numberOfPages)
    {
        return;
    }

    // replace the placeholder if necessary
    InspectionPageTableViewController *controller = [self.viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [self.storyboard instantiateViewControllerWithIdentifier:@"InspectionPageTableViewController"];
        [self.viewControllers replaceObjectAtIndex:page withObject:controller];
    }

    // Add page to controller
    controller.pageModel = [self.inspectionModel.pages objectAtIndex:page];

    // add the controller's view to the scroll view
    if (controller.view.superview == nil)
    {
        CGRect frame = self.scrollView.frame;
        frame.origin.x = CGRectGetWidth(frame) * page;
        frame.origin.y = 0;
        controller.view.frame = frame;

        [self addChildViewController:controller];
        [self.scrollView addSubview:controller.view];
        [controller didMoveToParentViewController:self];
    }
    [controller.tableView reloadData];
}

虽然 InspectionViewController 成功解除分配,但 InspectionPageTableViewController 在此处使用

行实例化
controller = [self.storyboard instantiateViewControllerWithIdentifier:@"InspectionPageTableViewController"];

...从来没有。

我已经尝试从这个 object 的超级视图中删除 InspectionPageTableViewController,并尝试从这个 object 中以其他方式添加到的任何和所有视图中删除它(尽管这个似乎毫无意义,因为调用 object 无论如何都会成功解除分配)。此外,在此 class 和 InspectionPageTableViewController class 本身之外没有出现字符串 "InspectionPageTableViewController"。

我对 UIStoryboard 方法 -instantiateViewControllerWithIdentifier: 表示怀疑,但我在 SO 上看到了几个答案,它们说它 returns 一个自动释放 object。所以这不是问题。

有人可以告诉我这是怎么回事吗?如果对 object 有更多的强引用,我肯定能够在 Instruments 中看到历史记录中的保留事件吗?

仔细看了你写的,我认为有两个可能的原因:

2) 您错误地使用了视图控制器包含。 VC 遏制是出了名的棘手。您可能没有将其从 self.childViewControllers 中删除(使用此包含删除操作的正确方法调用)

3) 如果要向导航控制器添加 VC,则应使用推送和弹出,而不是包含。

所以有几处错误。我没有在 Instruments 中启用 'Record reference counts',所以我没有得到完整的图片。完整图片如下所示:

在这一切中间的调用,tableView:viewForHeaderInSection 保留,涉及一个对象,InspectionPageTableViewController 将其自身设置为委托。遗憾的是,该对象的代表 属性 是 'strong'。一旦设置为 'weak',对象就会按预期自动释放。所以,再一次,'usual suspects'.

之一