5

我有一个 iPad 应用程序,它有很多屏幕和很多 segue 选项。目前,我只是使用 performSegueWithIdentifier 来启动这些 segue,我担心随着用户执行越来越多的 segue,我会占用大量内存。我看到人们推荐使用函数 popToRootViewControllerAnimated: if using a UINavigationController,但问题是我没有使用。我怎样才能阻止VC的数量激增?该应用程序的工作方式是,用户确实会不断返回到根 VC - 实际上是一个搜索屏幕。因此,如果我可以在需要这样的 segue 时清除 VC 堆栈,我认为这将解决我的问题,但我不知道如何解决这个问题。感谢您的任何建议。

4

4 回答 4

10

当您使用 segues 时,流程会前后移动。当用户向后移动(即按下“返回”)时,它不会推送到新的 VC,但会弹出到已经存在的 VC。当你弹出时,当前的 VC 将从堆栈和内存中删除。

如果您在流程中向后移动,那么这是错误的。你只需要继续前进。

为 SEGUE 做好充分准备

在为 segue 做准备时,您永远不应该创建自己的视图控制器并推送给它们。故事板可以为您完成所有这些工作。

一个适当的 prepareForSegue 方法应该看起来像这样......

- (void)prepareForSegue:(UIStoryBoardSegue*)segue
{
    if([segue.identifier isEqualToString:"SomeSegue"])
    {
        MyNewViewController *controller = segue.destinationViewController;

        controller.someProperty = "some value to pass in";
    }
}

这就是你所需要的。请注意,仅当您打算将一些信息传递给新的视图控制器时才需要它。如果你没有向前传递任何东西,那么你根本不需要这个方法。

当方法结束时,新的 VC 将被情节提要文件推送到屏幕上。

放松赛格

如果您有一个随机流程(如您的评论),那么您可以使用 unwind segues 来实现这一点。

在您的“A”视图控制器中,具有类似...的功能

- (IBAction)someUnwindAction:(UIStoryboardSegue*)sender
{
    //some action to run when unwinding.
}

它需要接收一个 UIStoryboardSegue 对象。如果设置为 IBAction,您也可以从 Interface Builder 访问它。

现在,当您想去 A > B > C > B > A 时,只需使用标准的推送和弹出(从 segue 和后退按钮)。

当你想去 A > B > C > A 时,你可以使用控制器 C 的 unwind segue。

如果你在控制器 C 中有一个取消按钮或其他东西,它在 Interface Builder 中,这应该带你回到控制器 A。然后在控制器 C 下方的 Interface Builder 中,你将有一个带有门和箭头指向的绿色小方块出它。只需将取消按钮的动作指向该符号并选择“someUnwindAction”。(注意,unwindAction 在 A 中,按钮在 C 中。)然后 XCode 使用它把你一直弹出到 A 并处理删除任何内存和东西。如果您愿意,您也可以将其他信息发送回 A。

如果您想以编程方式从 C 访问此展开转场,那么您可以运行...

[self performSegueWithIdentifier:"someUnwindAction" sender:nil];

这也将弹回 A。

于 2013-01-01T10:36:53.350 回答
1

恕我直言,我没有看到使用 segues 的任何问题,它比其他任何事情都简单得多。如果您担心内存消耗,那么只需分析您的应用程序并查看它消耗了多少以及您的“内存压力处理程序”被调用的频率。

于 2013-01-01T11:26:09.957 回答
0

好的,我相信我已经弄清楚了。它似乎工作。

由于我不断返回到一个普通的 VC,我将代码放置在我想重新回到这个“根”VC 以清除 VC 堆栈的地方。

我仍然在我的正常代码中执行实际的 segue

[self performSegueWithIdentifier:@"editBackToSearch" sender:self]; 

但是在“prepareForSegue:”方法中,我不再创建新的 VC 对象,而是执行我未完成的任何工作(保存我的数据),然后使用以下代码清除 VC 堆栈。

UIViewController *vc = self;
while ([vc presentingViewController] != NULL)
{
    vc = [vc presentingViewController];
}   
[vc dismissViewControllerAnimated:NO completion:nil];

它似乎运行平稳,并具有释放这些 VC 吸收的内存的预期影响(通过分析器确认)。

最后一条评论 - 由于某种原因,我无法为解雇命令设置动画,这似乎触发了无限循环并导致 EXC_BAD_ACCESS。将动画设置为 NO,但效果很好。

谢谢你的帮助。

于 2013-01-02T01:48:31.027 回答
0

Swift 3:这是为了防止 Swift 3 和 4 中的内存泄漏

@IBAction func entryViewSelected(_ sender: UIButton) {

    self.dismiss(animated: true, completion: nil)
}
于 2019-05-07T02:51:25.073 回答