Как остановить NSTimer, который я не знаю, выпущен или нет - PullRequest
0 голосов
/ 29 сентября 2011

Извините, что задал этот вопрос, но сейчас 3-й день. Я пытаюсь решить эту проблему и пока не достиг прогресса.

Проблема заключается в следующем: во время игры между пользователем, ответившим на вопрос и следующим вопросом, возникает пауза. Также в некоторых других случаях есть такие паузы в игровом процессе. Для этого я использую один NSTimer.

В .ч у меня есть:

@property(nonatomic,retain) NSTimer *scheduleTimer;

и в .м

@synthesize scheduleTimer;

scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];

теперь это работает просто отлично. Но когда пользователь выходит из ViewController, мне нужно отключить таймер. В противном случае таймер сработает, а затем завершит работу приложения или отобразит всплывающие окна, которые не принадлежат другому представлению и т. Д.

Поэтому я пишу:

- (void)viewWillDisappear:(BOOL)animated {
    [scheduleTimer invalidate];   
}

теперь это делает работу, если таймер действительно установлен. Но если такого таймера не запланировано, приложение просто вылетает.

Я испробовал, вероятно, все, что есть, включая @try (что также приводит к сбою приложения, Zombie говорит: "* - [CFRunLoopTimer invalidate]: сообщение отправлено на освобожденный экземпляр 0x567640"). Так как таймер освобождается после того, как он сделан, [scheduleTimer isValid] также просто завершит работу приложения.

Теперь я уже в отчаянии, и в крайнем случае я подумываю заменить таймер на UIView animateWithDuration, который ничего не делает.

Однако я думаю, что это должно быть довольно стандартной ситуацией. Я просто не знаю, почему я не могу найти ответ на эту очень очевидную задачу. Вы можете помочь? Спасибо

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

Я думаю, что проблема в том, что NSTimer автоматически выпускается перед вами invalidate.

Итак, вы должны сделать:

scheduleTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO] retain];

И вы также должны release таймер в viewWillDisappear:

[scheduleTimer release];

Но еще лучшим решением, вероятно, является использование синтаксиса свойства точки для сохранения / освобождения:

self.scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];

А потом:

- (void)viewWillDisappear:(BOOL)animated {
    if (self.scheduleTimer != nil) {
        [self.scheduleTimer invalidate];
        self.scheduleTimer = nil;
    }
}
0 голосов
/ 29 сентября 2011

Создайте метод для аннулирования таймера, который также устанавливает для свойства значение nil:

- (void) invalidateTimer
{
    if (self.scheduleTimer) {
       [self.scheduleTimer invalidate];   
       self.scheduleTimer = nil;  
    }
}

..., а затем вызывайте этот метод всякий раз, когда вы аннулируете таймер.Например:

- (void)viewWillDisappear:(BOOL)animated 
{
   [super viewWillDisappear: animated];
   [self invalidateTimer];
}

Убедитесь, что ваш таймер удерживается с помощью:

self.scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];

...