如何在注销操作中取消分配uiviewcontroller / unload视图

时间:2012-01-05 18:26:50

标签: iphone ios xcode ios4 ios5

我认为这是一个非常常见的用例,因为我已在多个应用中看到它。但经过几天的努力,我仍然在努力解决这个问题。我有如下结构:

UITabBarController
-- UINavigationController1
 ---- UITableViewController1

-- UINavigationController2
---- UITableViewController2

现在我在UITableViewController2上有一个注销按钮。当我点击该注销按钮时,我想要取消分配所有和任何视图控制器,所有视图都被卸载。基本上就像启动应用程序一样开始。我基本上希望再次调用每个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不同的行为。我这里没有使用任何模态viewcontroller。任何陷阱?

更新:我没有使用ARC

感谢 MBH

3 个答案:

答案 0 :(得分:2)

你的for循环将释放并因此解除你已经推送到相应UINavigationController根目录的任何视图控制器(取决于你有多少个选项卡),即当你弹回到根目录时它们将没有超级视图每个导航控制器,这些都是自动解除分配的。这些是你的UITableViewControllers。

对于相应的UINavigationControllers,您需要使用tabbar-controller来释放旧实例。恕我直言,当你发布UITabBarController时,应该为你完成。

然后离开UITabBarController本身。我认为不能做到这一点。您的代码将仅删除视图,但不会释放tabbar控制器本身。正如Krishna K指出的那样,你需要至少一个视图控制器来重新加载所有其他视图控制器。 将代码放入appdelegate是有道理的,但是你需要确保你的logout()不会导致UITableViewController2以及UITabbarController的保留,因为它是从某个地方的UITableViewController2调用的。

要探索的一个想法是,您的AppDelegate是否将实例保存到TabBar-Controller,您可以在从self.window中删除视图后释放并创建新实例?

// 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];
}

但正如我所说,此时可能会有关于内存管理的警告。

答案 1 :(得分:1)

您需要释放视图控制器。当调用它们的release方法时,该方法应该包含释放其所有对象资源的语句(并且还释放其超类)。

答案 2 :(得分:1)

两个导航控制器的rootViewController都是各自的TableView控制器。所以我认为popToRootViewController不会做任何事情。

您可能需要重置数据并刷新视图,而不是取消分配视图。