被推送后保持对iPhone UIViewController的引用

时间:2011-07-14 18:17:34

标签: iphone objective-c uiviewcontroller

我的问题是这个...在将UIViewController推送到导航控制器之后,在UIViewController之前的UIViewController中保持对UIViewController的引用有什么优缺点,这被认为是很好的编程习惯。这是用来演示我的问题的代码。

保持参考

标题

MainMenuViewController *mainMenuController;
@property (nonatomic, retain) MainMenuViewController *mainMenuController;

主要

if (self.mainMenuController == nil)
{
    //Goto the next page
    MainMenuViewController *controller = [[MainMenuViewController alloc] init];
    self.mainMenuController = controller;
    [controller release];
}
[self.navigationController pushViewController:mainMenuController animated:TRUE];

不保留参考

MainMenuViewController *controller = [[MainMenuViewController alloc] init];
[self.navigationController pushViewController:controller animated:TRUE];
[controller release];

6 个答案:

答案 0 :(得分:1)

如果不了解您的实施情况,很难说。

如果保留的视图控制器包含一堆沉重的,非视图的依赖对象(可能是数据源),如果用户没有做任何事情来调用该视图,那么你可能会使用一块内容丰富的内存。在它第一次加载后再次出现。

另一方面,如果加载视图和/或控制器由于某种原因是昂贵的,并且您确定用户将经常访问它,保持视图控制器可能是一个好主意并使您的应用程序更多响应。

如果您确实选择按住视图控制器,请确保对内存警告做出响应并在必要时转储控制器。

顺便说一句,如果你想保存几个键击并在以后阅读代码时立即明确你的情况,你可以这样做来测试nil-ness:

if (!self.mainMenuController)

答案 1 :(得分:1)

鉴于你的例子中的类被称为MainMenuViewController,我会说在这个例子中正确的事情是保持对象存活,因为它听起来像用户将继续回来的那种东西至。视图控制器通常是轻量级的,当内存变低时会脱离屏幕外视图,当它们再次可见时重新创建它们。您应养成设置任何内容(不仅仅是视图)的习惯,这些内容可以在-viewDidLoad中进行类似处理,并在-viewDidUnload中将其删除。

如果您是从动态列表中选择推送视图控制器,例如邮件应用程序在您选择邮件时执行的操作,您可能不会费心保留引用,尽管您可能希望保留一个到最近的视图控制器,以便在用户错误地按下后退按钮时,通过返回到之前的详细视图中完全相同的状态来更宽容。

答案 2 :(得分:1)

保存引用更多地是关于您的使用情况。如果您正在推动将来通常使用的视图控制器,那么您将希望保留对它的引用。但是,如果它是一次性使用视图,您可能不想保留它。或者您可能希望保留它,因此您只需加载一次。

或者,如果您有一个xib为您加载视图,那么您将保留对该视图的引用,除非您希望每次要使用它时都从xib重新加载。

例如,如果要将带有Web视图的视图加载到导航控制器中。您可能想要加载它。设置网址,以便加载页面。然后,当用户让用户从那里浏览网页时,将其交给导航控制器。

但是,如果您将主页推入堆栈,则可以将命令从其他页面发送回该页面。您需要保留View,以便您可以让他们在后续页面中执行的操作通过协议,应用程序代表或您可以使用的任何其他参考手段逐步返回主页。

无论哪种方式,你都必须做出这种区分。请记住,保留太多记忆会给你一个警告,那时你需要优先考虑你想要保留的东西以及你可以摆脱的东西。这是应用程序设计变得有趣的地方:)

希望有所帮助。祝你好运

答案 3 :(得分:0)

这取决于应用程序的要求。假设您想在推送导航堆栈之前向主控制器添加或删除某些东西,那么我们已经可以分配mainController并执行我们想要做的任何事情。我告诉我一个例子我在我的情况下做的是我需要在tableView上显示一些数据让我们说tableView在viewController2中我在viewController1上获取该表的数据源所以在我推动viewController2之前我初始化viewController2保持它的引用并将数据源分配给viewController2和reload表。这是我保留参考的理由。

答案 4 :(得分:0)

正如您所指出的,请继续参考。正如单词描述的那样,它是创建者对象和正在创建的对象之间的单向关系。因此,保持关系的需要是能够与创建的对象进行通信。如果你没有参考,你就无法与它交谈。因此,无论何时设计需要与新创建的对象进行对话的内容,都需要保留对它的引用。

答案 5 :(得分:0)

您在两个视图控制器之间创建了不合需要的耦合。您正在写一篇文章,MainViewController将始终拥有MainViewController类型的父级。这是一个不必要的限制。将来,您可能希望直接从另一个视图控制器实例化和加载MainViewController。

通常,在使用UINavigationController时,每个视图控制器都不应该假设其父视图控制器的类型。

更好的方法是使用委托/协议模式。

标题

@protocol MainViewControllerProtocol;
@interface MainViewController : UIViewController {
    id <MainViewControllerProtocol> delegate
}
    @property (nonatomic, assign) id <MainViewControllerProtocol> delegate;
@end

@protocol MainViewControllerProtocol <NSObject>
    - (void)somethingHappened;
@end