2011-09-06 45 views

回答

1

我結束了在每個視圖控制器上實現Cleanup()方法。設置視圖控制器以觀察來自NSNotification.DefaultCenter的某個通知。當時間到來PopToRootViewController()然後發佈該通知事件。觀察這個通知的視圖控制器將被設置爲運行Cleanup(),這將安全地清理所有的refs和內存。

+1

如果您繼承UINavigationController,那麼您可以在調用方法之前或之後攔截對popToRootViewController的所有調用。值得記住的是,popToRootViewController返回一個NSArray *,其中包含從堆棧中彈出的所有viewController,因此您可以將清理消息發送給它們。請參閱下面的答案。 –

1

您需要實施UIViewController.viewDidUnload()方法,它在將視圖彈出到根或先行視圖時調用。 爲了讓您的應用程序更輕,您也可以管理UIViewController.View[Will|Did]Disappear()中的一些控制器項目,但是您必須小心,因爲在將另一個視圖推向當前視圖時也會調用它們,因此請注意不要清潔您的項目依賴於你的視圖彈出回來。

+1

我覺得有周圍的一些混亂時viewDidUnload被調用。根據[iOS](http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html)文檔,它只在低內存情況下被調用。我證實,當視圖彈出堆棧時,卸載並不總是被調用。實際上卸載並不明確指向UINavigationController。 –

+0

你是對的'Andrew Young',並不保證每次從導航控制器彈出時都會調用'viewDidUnload'。 – thesummersign

+0

感謝這些精度,我每次都會發誓它被稱爲,但它可能是一個巧合的問題。我會更加小心'關於未來的發展,謝謝你們兩位! – psycho

2

爲了達到這個目的,我傾向於繼承UINavigationController,以便在發送到超級視圖後攔截所有對popToRootViewController的調用。

popToRootViewController返回一個NSArray *,其中包含所有已從堆棧彈出的UIViewController,因此您可以將清理消息發送給它們。例如:

@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 

} 
相關問題