NSTimer Uniqe вопрос - PullRequest
       25

NSTimer Uniqe вопрос

0 голосов
/ 06 мая 2011

Я пойду прямо к проблеме.

Эти едят мою голову с недели.

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

if(timerRefresh)
{
    //[timerRefresh invalidate];
    timerRefresh = nil;
}

if (!self.isConnectionAvailable) {
    timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}
else if (self.isLivePresent||self.isUpcomingMatchToday) {
    timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}
else {
    timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}

NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
[runLoop addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
[runLoop run];

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

Я надеюсь, что этоправильный путь.

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

-(void)teamNameClicked:(id)sender
{
    BOOL result = YES;
    NSNumber *newNumber = [NSNumber numberWithBool:result];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"PauseMatchesLiveMatchTimer" object:newNumber];

    [self performSelector:@selector(sendTeamNameClickToFunction:) withObject:sender];
}

, и когда операция завершается, у меня есть другой уведомитель как этот ...

-(void)processTeamNameClick:(id)sender
{
    UIButton *button = (UIButton *)sender;
    selectedIndexDropDown  = button.tag;

    [self parseTeamFile:button.tag];
    self.lblDropDown.text = [dictTeamFilter valueForKey:[NSString stringWithFormat:@"%i",button.tag]];
    [tblResults performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

    BOOL result = NO;
    NSNumber *newNumber = [NSNumber numberWithBool:result];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"PauseMatchesLiveMatchTimer" object:newNumber];
}

Обратите внимание на ДА и НЕТ для результатов ..

Теперь это наблюдатель для уведомления ...

-(void)pauseAndResumeTimer:(NSNotification *)notification;
{
    NSNumber *newNumber = [notification object];
    BOOL result = [newNumber boolValue];

    if (result) {
        if(timerRefresh)
        {
            if ([timerRefresh isValid])
                [timerRefresh invalidate];
            timerRefresh = nil;
        }
    }
    else 
    {
        if(timerRefresh)
        {
            if ([timerRefresh isValid])
                [timerRefresh invalidate];
            timerRefresh = nil;
        }

        if (!self.isConnectionAvailable) {
            timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }
        else if (self.isLivePresent||self.isUpcomingMatchToday) {
            timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }
        else {
            timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }

        NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
        [runLoop addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
        [runLoop run];
    }
}

Когда процесс фильтрации включен, я останавливаю родительский таймер.А когда выкл, я запускаю его снова.

Хорошо ... Итак, теперь проблема ... Когда я делаю нормальную навигацию на своих страницах, она работает абсолютно нормально ... как переключение вкладок, переход между страницами и т. Д.

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

Если кто-то может искренне помочь мне, пожалуйста, сделайте.Заранее спасибо.

1 Ответ

0 голосов
/ 07 мая 2011

В вашем коде происходят забавные вещи:

  • Прежде всего, я, по крайней мере, на 90% уверен, что вы не хотите вызывать [[NSRunLoop mainRunLoop] run] в любом из методов вашей программы - эти методы вообще завершаются или вы продолжаете агрегировать поток за потоком?
  • Во-вторых, все ваши недействительные таймеры немного странные:
    1. Нет смысла в if (timerRefresh) if ([timerRefresh isValid]) [timerRefresh invalidate];; так как в Objective C обмен сообщениями nil - это прекрасно. Результатом такого сообщения всегда является 0x0, поэтому первый if не нужен, а второй в любом случае оценивается как NO.
    2. Аннулирование таймера означает удаление его из цикла запуска, на котором он был запланирован. Следовательно, второй if также не нужен - оставляя вам только [timerRefresh invalidate];.
    3. Чтобы -[NSTimer invalidate] имел эффект, необходимо вызвать в потоке, на который запланирован таймер. Из того, что я понял, это не так во всех ваших методах. Поэтому вы должны использовать performSelectorOnMainThread:withObject:waitUntilDone: с соответствующими аргументами.
  • Нет никакой разницы между [self performSelector:@selector(sendTeamNameClickToFunction:) withObject:sender] и просто [self sendTeamNameClickToFunction:sender]. За исключением того, что последний намного легче читать; -)
  • Предложения if в pauseAndResumeTimer: не имеют большого смысла, т. Е. Много дублирования кода.

Вот этот метод приведен в порядок и с аннулированием, происходящим в основном потоке:

-(void)pauseAndResumeTimer:(NSNotification *)notification
{
    [timerRefresh performSelectorOnMainThread:@selector(invalidate) withObject:nil waitUntilDone:YES];
    timerRefresh = nil;

    NSNumber *result = [notification object];
    if ([result boolValue]) return;

    if ( !self.isConnectionAvailable || self.isLivePresent || self.isUpcomingMatchToday ) {
        timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
    } else {
        timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
    }

    [[NSRunLoop mainRunLoop] addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
}
...