iPhone 设计模式 &内存管理问题
在我的 iPad 应用程序中,我有一个 UINavigationController 和多个充当选项卡的 viewController。我没有使用 UITabbarController,因为我想要对选项卡进行某些自定义外观,因此一直在加载不同的控制器,这些控制器是单个 UITableViewController 的子类,该控制器封装了整个表格视图和单元格逻辑,只需点击充当选项卡的图标按钮即可屏幕底部。
看看我实现的设计,我实际上并不需要导航控制器,因为我不需要推送/弹出视图[我现在正在做]并且希望一次有一个视图控制器。
我现在所做的是:
在 appDelegate 的 didFinishLaunchingWithOptions 方法中,我将导航控制器分配为:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UINavigationController *navigationVC = [[UINavigationController alloc]init]; navigationVC.navigationBarHidden = YES; navigationVC.navigationBar.barStyle = UIBarStyleBlack; self.navigationController = navigationVC; [window addSubview: [self.navigationController 视图]]; [navigationVC发布]; //设置方向为纵向 self.currentOrientationType = 肖像; //从启动屏幕视图控制器开始 [self setViewController:LAUNCH 参数:nil]; 返回是; }
在我的方法 setViewController:param: 中,根据传递给它的 ID,它加载相应的 viewController,如下所示:
- (void)setViewController:(NSString *)ID param:(NSString *)param {
UIViewController *viewController;
if(ID == HOME) {
viewController = [[HomeScreenViewController alloc]initWithNibName:@"HomeScreenViewController" bundle:nil];
}
else if(ID == ...){
}
...
//push the specified view controller
[self setTransitionType:nil];
[[self navigationController] initWithRootViewController:viewController];
[viewController release];
}
}
发生的情况是我的任何 viewController 都被初始化,因为 rootViewController 没有被释放。看来每次为每个新的 viewController 初始化 navigationController 这种方式是错误的,因为它保留了对其根视图控制器的引用,并且我一次又一次地初始化它,而不关心它在早期 viewController 上保留的引用计数。
当我在任何时间点只想要一个 viewController 时,什么是更好的方法?
In my iPad application, I have a single UINavigationController and multiple viewControllers acting as tabs. I'm not using the UITabbarController since I wanted certain custom look for the tabs, so have been loading the different controllers which are subclass of a single UITableViewController that encapsulates the whole tableview and cells logic on tap of the icon buttons acting as tabs at the bottom of the screen.
Looking at the design I have implemented I don't really need a navigationController as I don't need to push/pop views [which I'm doing right now] and want a single viewController to be there at a time.
What I have done now is:
In my didFinishLaunchingWithOptions method in my appDelegate, I'm allocating my navigation controller as:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UINavigationController *navigationVC = [[UINavigationController alloc]init]; navigationVC.navigationBarHidden = YES; navigationVC.navigationBar.barStyle = UIBarStyleBlack; self.navigationController = navigationVC; [window addSubview: [self.navigationController view]]; [navigationVC release]; //set orientation as portrait self.currentOrientationType = PORTRAIT; //start with launch screen view controller [self setViewController:LAUNCH param:nil]; return YES; }
And in my method setViewController:param:, depending upon the ID passed to it, it's loading the appropriate viewController as below:
- (void)setViewController:(NSString *)ID param:(NSString *)param {
UIViewController *viewController;
if(ID == HOME) {
viewController = [[HomeScreenViewController alloc]initWithNibName:@"HomeScreenViewController" bundle:nil];
}
else if(ID == ...){
}
...
//push the specified view controller
[self setTransitionType:nil];
[[self navigationController] initWithRootViewController:viewController];
[viewController release];
}
}
What is happening is any of my viewControllers thus inited as rootViewControllers aren't getting deallocated. It seems that initing the navigationController every time for each new viewController this way is wrong as it keeps a reference to its root view controller and I'm initialising it again and again with no concern to the reference count it kept on earlier viewController.
What would be a better approach as I want only one viewController there at any point in time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据Apple文档,initWithRootViewController创建了一个新的导航控制器实例。每次调用 setViewController 方法时,您都会创建一个新的导航控制器实例。相反,您需要使用 initWithRootViewController 创建一个视图,然后使用 PushViewController 方法来创建您想要成为活动视图的视图。
According to Apple document, initWithRootViewController creates a new instance of navigation controller. You are creating a new instance of navigation controller every time you call your setViewController method. Instead, you need to create one with initWithRootViewController and use PushViewController method thereafter for the view that you want to be the active one.