0

请帮我理解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 是否已释放?

4

2 回答 2

0

查看NSTimer的文档。特别是scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:方法。该文档指出

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

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

于 2013-08-07T01:15:01.723 回答
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];
}
于 2013-08-07T02:06:29.450 回答