我认为这是一个非常常见的用例,因为我在多个应用程序中都看到过它。但是在花了几天之后,我仍在为此苦苦挣扎。我有如下结构:
UITabBarController
-- UINavigationController1
---- UITableViewController1
-- UINavigationController2
---- UITableViewController2
现在我在 UITableViewController2 上有一个注销按钮。当我单击该注销按钮时,我希望所有和任何 View Controller 都被释放,所有 View 都被卸载。基本上就像启动应用程序一样重新开始。我基本上希望再次调用每个 UITableViewController 上的 viewDidLoad。
当对 UITableViewController2 执行注销操作时,我尝试在我的 appdelegate 中调用以下方法。
-(void) logout {
for (UINavigationController* ctrl in self.tabBarController.viewControllers) {
[ctrl popToRootViewControllerAnimated:NO];
ctrl.visibleViewController.view = nil;
}
[self.tabBarController.view removeFromSuperview];
[self.window addSubview:self.tabBarController.view];
但是,唉,它似乎不起作用?
知道这样的事情是如何完成的吗?我还看到 iOS4 与 iOS5 中使用 visibleViewController 时的不同行为。我在这里没有使用任何模态视图 Controller 。有什么问题吗?
gia hạn:我没有使用 ARC
谢谢英里每小时
您的 for 循环将释放并因此释放您已推送到相应 UINavigationController 根的任何 View Controller (取决于您有多少个选项卡),即因为当您弹出回到根时,这些将没有 super View 每个导航 Controller ,这些都是自动释放的。这些是您处理的 UITableViewControllers。
至于相应的 UINavigationControllers,您需要您的 tabbar-controller 来释放旧实例。恕我直言,这应该在您发布 UITabBarController 时为您完成。
这就留下了 UITabBarController 本身。我不认为这是可以做到的。您的代码只会删除 View ,但不会释放标签栏 Controller 本身。正如 Krishna K 指出的那样,您至少需要一个 View Controller 来重新加载所有其他 View Controller 。将代码放入 appdelegate 中是有意义的,但您需要确保您的 logout() 不会导致 UITableViewController2 以及 UITabbarController 上的保留,因为它是从 UITableViewController2 某处调用的。
一个探索的想法,您的 AppDelegate 是否持有 TabBar-Controller 的一个实例,您可以在从 self.window 中删除 View 后释放并创建一个新实例?
// manually create UITabBarController - AppDelegate holds instance
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
mytabcontroller=[[UITabBarController alloc] initWithNibName:@"foo" bundle:nil];
}
- (void) logout {
[self.tabBarController.view removeFromSuperview];
[mytabcontroller release];
mytabcontroller=[[UITabBarController alloc] initWithNibName:@"foo" bundle:nil];
[self.window addSubview:self.tabBarController.view];
}
但正如我所说,此时内存管理可能需要注意。
Tôi là một lập trình viên xuất sắc, rất giỏi!