解散后未释放 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'.
之一
所以我 运行 解决了一个似乎已经在这里一次又一次解决的问题。不幸的是,我无计可施,所以我会 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'.
之一