navigationController在pop后继续运行

时间:2013-08-07 01:05:19

标签: iphone ios objective-c

请帮我理解navigationController的神秘面纱。我有一个从didFinishLaunchingWithOptions调用的HomeViewController。从HomeViewController用户按下一个按钮,我的代码是

-(IBAction)showMap:(id)sender
{
    MapViewController *mapViewController = Nil;
    mapViewController = [[MapViewController alloc] initWithNibName:@"MapView-iPad" bundle:nil];
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate.navigationController pushViewController:mapViewController animated:YES];
}

当用户想要从MapViewController返回时,我使用代码

-(IBAction)goBackToHome:(id)sender
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate.navigationController popViewControllerAnimated:YES];
}

我的印象是,一旦我离开MapViewController,我的所有资源都被释放与MapViewController相关联。验证我是否将此代码放在MapViewController中的initWithNibName中。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization
    [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(printMessage) userInfo:nil repeats:YES];
 }
 return self;
}

-(void) printMessage
{
     NSLog(@"I am inside Map View Controller");
}

令我惊讶的是,即使在弹出MapViewController之后,printMessage仍然继续。请帮助我了解正在发生的事情以及为什么MapViewController仍在运行。有什么方法可以验证MapViewController是否已被释放?

2 个答案:

答案 0 :(得分:0)

看看documentation for NSTimer。特别是scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:方法。文档指出

  

<强>靶   计时器触发时,由aSelector指定的消息发送到的对象。目标对象由计时器保留,并在计时器失效时释放。

这意味着您的计时器会导致MapViewController被保留。如果没有该计时器保持对控制器的引用,当您从导航控制器弹出它时,它确实应该被释放。

答案 1 :(得分:0)

MapViewController仍然保留:计时器保留ViewController,计时器由其计划的运行循环保留。要让MapViewController被释放,您必须使用[yourTimer invalidate]从运行循环中删除计时器。一种方法是在MapViewController

中保留对计时器的弱引用
@property (weak) NSTimer *timer;

创建计时器时,将其分配给属性:

self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(printMessage) userInfo:nil repeats:YES];

现在,您可以在不再需要时使计时器无效,例如在viewWillDisappear

- (void)viewWillDisappear {
    [self.timer invalidate];
    [super viewWillDisappear];
}