NSTimer останавливается в первый раз, когда я говорю это, затем отказывается останавливаться - PullRequest
0 голосов
/ 27 января 2011

Я объявил NSTimer в своем заголовке UIViewController следующим образом:

NSTimer *mainTimer;

И я запускаю его в реализации метода viewWillAppear, поэтому:

mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

У меня есть кнопка, которая переворачивает представление (стандартный шаблон служебного приложения) с именем showInfo, и она имеет команду:

[mainTimer invalidate];

Когда мое приложение запускается, таймер запускается и работает. Когда я нажимаю эту кнопку в первый раз, и вид переворачивается, таймер останавливается. Когда я закончу с flipSideViewController и снова появится главный вид, таймер снова запустится. Пока хорошо. Проблема в том, что последующее нажатие кнопки (и, следовательно, вызов [mainTimer invalidate] не приводит к остановке таймера. Он просто продолжает работать. Я могу переворачивать все, что хочу, и он продолжает обновляться. Для ухмылок я ставлю два invalidate звонит подряд, но это вылетает.

UPDATE:

Нашел проблему. По возвращении из flipSideViewController я сам звонил viewWillAppear, что бы создать таймер. Цикл выполнения также автоматически вызывает viewWillAppear, поэтому был создан второй таймер. Это произошло только после того, как я однажды посетил оборотную сторону, поэтому таймер (единичный случай) нормально останавливался, когда я переворачивал в первый раз. Странно, что я могу создать два таймера с одним и тем же именем ...

Ответы [ 4 ]

3 голосов
/ 27 января 2011

Как только таймер становится недействительным, он никогда не сработает снова.

Таким образом, если «таймер продолжает работать», то это другой таймер. Убедитесь, что вы говорите с примерами, которые вы считаете. Я видел довольно много ошибок, когда разработчик выделял / инициировал экземпляр, а затем загружал NIB и заставлял вступать в игру другой экземпляр определенного класса. Я мог видеть, что нечто подобное происходит здесь.

Обратите внимание, что невозможно сделать недействительным таймер в освобождении объекта, который является целью таймера. Таймер сохранит цель, и, таким образом, цель не может быть [правильно] освобождена в пределах таймера, который сначала был признан недействительным.

2 голосов
/ 27 января 2011

Я просто сделал то же самое, и мне кажется, что это работает. Что я сделал в шаблоне xcode:

Перейдите в MainViewController.h и введите:

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
    NSTimer* timer;
}

@property (nonatomic, retain) NSTimer* timer;

- (IBAction)showInfo:(id)sender;

@end

Перейдите на MainViewController.m и добавьте:

@synthesize timer;

-(void) viewWillAppear:(BOOL)animated {
    NSLog(@"Timer!");
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];
}

-(void) updateAll {
    NSLog(@"run");
}

- (IBAction)showInfo:(id)sender {    
    [timer invalidate];
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

Только это, и это хорошо для меня. Это как-то помогает? Может быть, ваша проблема в другом месте - что вы делаете в updateAll?

1 голос
/ 27 января 2011

Возможно, viewWillAppear вызывается несколько раз.

Вы должны убедиться, что таймер недействителен перед его созданием

[mainTimer invalidate];
mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

Конечно, если вы также отключили таймер на некоторыхв другом месте, вы должны присвоить ему значение null.

[mainTimer invalidate];
mainTimer = NULL;
1 голос
/ 27 января 2011

Из документов для [NSTimer invalidate]:

Останавливает приемник снова и снова запрашивает его удаление из цикла выполнения.

Так что я бы назвал invalidateи затем отпустите свой таймер.Не похоже, что вы сохраняете таймер в первую очередь.Поэтому сохраните таймер, когда вы его сделаете, аннулируйте его, когда захотите, затем отпустите после аннулирования.

Следующий viewWillAppear, убедитесь, что вы создаете и сохраняете новый таймер.

...