Как правильно сделать недействительным мой таймер в NSRunLoop - PullRequest
1 голос
/ 20 сентября 2011

Я получаю информацию с сервера в своем приложении со значением secondsToEnd и запускаю счетчик после получения этой информации.

Мой проект содержит представление прокрутки, поэтому, чтобы обойти блокировку моего таймера из-за прокрутки, я добавляю таймер в NSRunLoop следующим образом:

[[NSRunLoop currentRunLoop] addTimer:timer
                             forMode:NSRunLoopCommonModes];

Я создал свойство NSTimer, которое называется «оригинальный», «таймер», и это весь фрагмент моей функции startTimer:

- (void)startTimer
{
    if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

    NSTimer * timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
                                               interval:1.0
                                                 target:self
                                               selector:@selector(timer:)
                                               userInfo:nil
                                                repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:timer
                                 forMode:NSRunLoopCommonModes];

    [self setTimer:timer];
    [timer release];
}

Причина, по которой проверка недействительна в методе start, состоит в том, что после того, как значение secondsToEnd достигнет 0, я получаю новый и снова вызываю startTimer.

И в моем методе dealloc у меня есть это:

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

Но это не становится недействительным? Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 20 сентября 2011

В каком порядке эти операторы, разделенные запятыми, выполняются? Что произойдет, если _timer равен нулю, когда вы звоните инвалиду или когда вы звоните релизу?

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

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

if ([_timer isValid]) {
    [_timer invalidate];
}
[_timer release];

В методе dealloc нет необходимости устанавливать _timer = nil, его хранилище исчезает после завершения этого метода.

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

Вы должны сначала позвонить [timer release], а затем timer = nil.То же самое в методе dealloc.Метод dealloc может не вызываться немедленно, если внешние объекты находятся в пулах автозапуска.В этих случаях он вызывается, когда система решает окончательно отбросить ваш объект.Так что это может занять некоторое время (если вы установите точку останова).

Кстати, я бы посоветовал избегать синтаксиса запятых и вместо этого использовать блоки в фигурных скобках.Гораздо проще читать.

...