NavigationController продолжает работать после pop

Пожалуйста, помогите мне разобраться в тайне navigationController. У меня есть HomeViewController, который вызывается из didFinishLaunchingWithOptions. Из пользователя HomeViewController нажмите кнопку, и мой код будет

-(********)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, я использую код

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

Мне показалось, что когда я вышел из MapViewController, все мои ресурсы освобождаются, связанные с MapViewController. Чтобы проверить, что я вставляю этот код в initWithNibName в MapViewController.

- (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 ответа

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


Взгляните на документацию для NSTimer. В частности, метод scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: method. В документации отмечается, что

<span>target</span> Объект, по которому отправляется сообщение, заданное aSelector при срабатывании таймера. Целевой объект сохраняется таймером и освобождается, когда таймер недействителен.

Это означает, что ваш таймер вызывает сохранение MapViewController. Без этого таймера, удерживающего ссылку на контроллер, он действительно должен быть освобожден, когда вы вытащите его из навигационного контроллера.

licensed under cc by-sa 3.0 with attribution.