调用PopToRootViewController后如何清理视图控制器?

时间:2011-09-06 18:08:39

标签: iphone ios uinavigationcontroller xamarin.ios

我有一个类似于this question的问题,但它是MonoTouch特有的。当我需要调用NavigationController.PopToRootViewController()时,我目前在堆栈上的第8个视图控制器上,我需要在所有视图控制器上清理一堆东西(引用,事件,图像等)弹出,我该怎么做?

3 个答案:

答案 0 :(得分:2)

为了实现这一点,我倾向于子类化UINavigationController,这样我就可以在发送到superview后拦截对popToRootViewController的所有调用。

popToRootViewController返回一个NSArray *,其中包含已从堆栈中弹出的所有UIViewControllers,因此您可以向它们发送清除消息。例如:

@interface BCNavigationController : UINavigationController 
@end

@implementation BCNavigationController


- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated {
    NSArray * poppedControllers =  [super popToRootViewControllerAnimated:animated];
    [self sendPoppedMessageToControllers:poppedControllers];
    return poppedControllers;
}

- (UIViewController *) popViewControllerAnimated:(BOOL)animated {
    UIViewController * poppedController = [super popViewControllerAnimated:animated];
    [self sendPoppedMessageToControllers:[NSArray arrayWithObject:poppedController]];
    return poppedController;
}

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated {
    NSArray * poppedControllers =  [super popToViewController:viewController animated:animated];
    [self sendPoppedMessageToControllers:poppedControllers];
    return poppedControllers;
}

- (void) sendPoppedMessageToControllers:(NSArray *)controllers {
    for (UIViewController * controller in controllers )
    {
        if ([controller respondsToSelector:@selector(viewWasPoppedOffStack)])
            [controller performSelector:@selector(viewWasPoppedOffStack)];
    }
}

@end

...然后,在你的孩子UIViewController

// MyViewController.m
- (void) viewWasPoppedOffStack  {

// do some cleanup

}

答案 1 :(得分:1)

您需要实现UIViewController.viewDidUnload()方法,在向根或先前视图弹出视图时调用它。 为了让您的应用程序更轻松,您也可以在UIViewController.View[Will|Did]Disappear()中管理一些控制器项目,但是您必须小心它们,因为在将另一个视图推送到当前视图时也会调用它们,所以请注意不要当您的视图弹回时,您依赖的清洁项目。

答案 2 :(得分:1)

我最终在每个视图控制器上实现了Cleanup()方法。设置视图控制器以观察来自NSNotification.DefaultCenter的特定通知。当有时间来呼叫PopToRootViewController()然后发布该通知事件。观察此通知的视图控制器将设置为运行Cleanup(),这将安全地清理所有引用和内存。