子类化 UIViewController 导致内存问题?

Posted

技术标签:

【中文标题】子类化 UIViewController 导致内存问题?【英文标题】:Subclassing UIViewController causing memory problems? 【发布时间】:2012-10-24 15:40:31 【问题描述】:

我正在继承 UIViewController 以防止我的“masterButtons”和“subButtons”集的代码重复。

这一切看起来都很好,直到我意识到在大约 1200 次页面更改之后 - 仅在 3 个空白页面之间导航(仅显示按钮和一些其他对象)应用程序将总是崩溃!

仪器(+ 在设备上进行测试)没有显示任何内存泄漏,但确实显示了这些按钮对象的数百个实例存在!(已选择“已创建且仍然存在”过滤器。) 此外,永远不会从任何 ViewController 调用 viewDidUnload / didReceiveMemoryWarning!

我在我的应用程序的其他页面上没有遇到这些问题(UIViewController 没有被子类化)。

所以看起来 ViewController 的内容正在重新创建,并且之前创建的任何内容都没有被删除。 子类化 UIViewController 是否有任何常见的陷阱可能会导致这种情况?有什么我可能会遗漏的吗?

建议将不胜感激。 (遇到这个问题,我想把我的 Mac 扔出窗外!

Top_ViewController      (contains 'MasterButtons')
       v
Area1_ViewController    (subclass of TOP_ViewController) (contains 'subButtons', and  a few texts fields etc.)
       v
aPage_ViewController    (subclass of Area1_ViewController)  (currently blank page)

(使用 ARC 和故事板。故事板视图控制器具有各自的“aPage_ViewController”作为它们的类。)

【问题讨论】:

如何/在哪里创建按钮?请显示一些代码... ios 6 下 viewDidUnload 已被弃用,并且永远不会被调用,因此如果您在其中做某事,您可能需要考虑更改应用程序的代码/行为以解决这些更改API。 是的,我将删除 viewDidUnload 方法。 (我会尽快发布一些代码......) 【参考方案1】:

如果您以循环方式创建故事板,则可能会一直创建新的viewControllers。每个 segue 转换都会创建新的viewController,因此可能没有内存泄漏,但您的内存将被消耗。

您应该使用UITabBarControllerUINavigationController 来回移动并且永远不要创建循环。

此外,viewDidUnload 在 iOS6 中已被弃用,也许您忽略了警告?

编辑:

试试这样的:

-(void)tab1_IsPressed:(UIButton *)paramSender
    Top_ViewController *target_VC = (Top_ViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"page_1"];
    [self.navigationController popViewControllerAnimated:NO];
    [self.navigationController pushViewController:target_VC animated:NO];

-(void)tab2_IsPressed:(UIButton *)paramSender
    Top_ViewController *target_VC = (Top_ViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"page_2"];
    [self.navigationController popViewControllerAnimated:NO];
    [self.navigationController pushViewController:target_VC animated:NO];

【讨论】:

我正在使用 UINavigationController 和这种技术来更改页面:Top_ViewController target_VC = (Top_ViewController)[self.storyboard instantiateViewControllerWithIdentifier:@"page2"]; [self.navigationController pushViewController:target_VC 动画:NO];我真的希望不要每次都创建一个新的 VC!有没有办法检查? 您可以在您的自定义视图控制器的viewWillAppear 方法中打印self,例如NSLog(@"%@", self);。然后在 viewControllers 之间切换并从控制台验证此地址是否保持不变。我建议您在 Interface Builder 中创建视图控制器,而不是从代码中创建,您可以将类属性设置为您的自定义类。 你有没有调用过popViewControllerAnimatednavigationController的方法? 谢谢,将检查控制台中的 VC 地址保持不变。当前每个页面的情节提要中有视图控制器 - 每个页面都有自己的类。但是不,我没有在这里使用 popViewControllerAnimated。但这有必要吗,因为我正在“推动”目标 viewController? 从我的答案的编辑部分尝试我的更改。

以上是关于子类化 UIViewController 导致内存问题?的主要内容,如果未能解决你的问题,请参考以下文章

使用 UITableView 子类化 UIViewController

如何在许多子类中使用 UITableViewDelegate 子类化 UIViewController

子类化 UIView/UIViewController

子类化 UIViewController 时调用 viewDidLoad 是啥?

动态子类化 UIViewController 的错误

子类化 UIViewController 实现 UITableView 委托和数据源:代码重用