Segues和viewDidLoad / viewDidUnload方法

时间:2012-09-03 15:52:53

标签: ios memory-management uistoryboard uistoryboardsegue

我正在制作简单的故事板应用程序,它有2个UIViewControllers,我正在使用模态segue在它们之间切换。每个UIViewController都有一个UIButton,用于执行另一个UIViewController的segue。在viewDidLoad方法中,我在每个UIViewController上为该UIButton的外观设置动画。我正在使用Cross Dissolve Modal segue。

当我在第一个UIViewController上按UIButton时,我导航到第二个UIViewController并执行动画并显示第二个UIViewController。在第二个UIView控制器上按UIButton后,首先显示UIViewController,然后执行动画。一切都很好看,每当我导航到它时,每个UIViewController都会调用viewDidLoad方法。这很棒。

我现在尝试将Modal segue类型从Cross Dissolve更改为XCode Interface Builder中默认提供的其他两个类型。我改为Cover Vertical,一切正常,没有变化。 但是当我尝试翻转水平模态segue 时,我发现了一个问题。

执行Flip Horizo​​ntal Modal segue时,会显示UIViewControllers上的UIButton,但动画未执行。我试过调试,我确信正在执行动画命令,但是没有显示动画。

这是我的第一个问题:有没有人知道这些类型的模态片段之间有什么区别可能导致我的动画没有出现?

其他问题与segue和内存管理的基本理论有关。当我执行segue并导航到某些UIViewController时,每次都会调用viewDidLoad方法。那么,这是否意味着我每次执行viewDidLoad方法时都会创建新的对象实例?

我还注意到 viewDidUnload方法永远不会被调用。因此,如果回答上一个问题是肯定的(每个viewDidLoad执行创建新的对象实例),这是否意味着我的UIViewController对象实例永远不会被卸载和删除?或者ARC正在幕后进行垃圾收集?

如果有人可以解释故事板segues和内存管理/对象生命周期的工作原理以及为什么从未调用viewDidUnload方法,我将非常感激。


[编辑#1:在执行模态segue后尝试卸载UIViewController]

[更新#1:不应该这样做,将自动调用viewDidUnload]

我在IBAction中制作segue附加到UIButton点击。我已经写了这个代码的和平来执行模态segue。

@try
{
    [self performSegueWithIdentifier:segueToPerform sender:self];
}
@catch (NSException *exception) 
{
    NSLog(@"Exception: %@", exception);
}
@finally
{
    [self viewDidUnload];
}

我在@finally块中手动调用了viewDidUnload,我检查了天气viewDidUnload在运行时被调用,是的 - 它被调用。

这是否意味着我设法卸载我在使用另一个UIViewController的模态segue导航到我创建的UIViewController对象时将其从内存中删除?

此方法是否定期替代:

[self dismissViewControllerAnimated:YES completion:nil];

因为上面的这一行将我返回到UIViewController,我从那里导航到当前的UIViewController,但这不符合我的需要,因为我需要从当前的UIViewController到其他UIViewControllers执行新的segue(除了返回UIViewController,我从中返回导航到当前的一个)?


[编辑#2:完成]

最后,在为这些UIViews创建单独的XIB文件后,我更改了实现模型并在单个UIViewController下加载了新的UIViews。我已经将@dasblinkenlight的答案标记为正确答案,因为它包含许多有用的信息,并且对该答案的讨论为使用模态segues提出了一些疑问。

2 个答案:

答案 0 :(得分:4)

我不知道你问题第一部分的答案,但是一旦你得知第二部分的答案,我相信你会采用不同的解决方案。

  每次调用

viewDidLoad方法。那么,这是否意味着我每次执行viewDidLoad方法时都会创建新的对象实例?

绝对。 “模态”segue导致新视图完全遮盖旧视图,直到新视图关闭。如果你来回多次,你的代码将在当前的代码下积累一整堆“视图”。

  

我还注意到永远不会调用viewDidUnload方法。因此,如果对上一个问题的回答是肯定的(每个viewDidLoad执行创建新的对象实例),这是否意味着我的UIViewController对象实例永远不会被卸载和删除?

这是正确的,您创建的所有视图控制器仍然存在,您可以在其上方关闭视图。

  

或者ARC正在幕后进行垃圾收集?

ARC不是垃圾收集器,它是一种引用计数机制,编译器具有一点自动化功能。对象仍在那里。

您应该将代码更改为

[self dismissModalViewControllerAnimated:YES];

在第二个控制器中,而不是使用模态segue将你带回第一个控制器。

答案 1 :(得分:0)

我遇到了一个类似的问题,我有一个复杂的VC导航网络,结果使用segues(没有UINavigationController)吸收了太多的内存。 您可能需要查看此问题/答案以查看我的最终解决方案。 uerceg和dasblinkenlight之间的对话帮助我找到了这个解决方案。

Segues and clearing historical ViewControllers from memory