Как убедиться, что определенный код выполняется не чаще 1 раза в 1 секунду? - PullRequest
1 голос
/ 15 сентября 2011

У меня есть программа, которая загружает тонны файлов из сети

У меня есть несколько потоков, загружающих данные.

После вызова каждой информации мне необходимо обновить контексты управляемого объекта

Если 10 потоков завершат загрузку примерно в одно и то же время, контекст управляемого объекта будет запущен 10 раз.

Правда в том, что мне нужно запустить его только один раз.

ЧтоЯ хочу сделать, это создать метод, который принимает блок.

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

Ответы [ 3 ]

2 голосов
/ 15 сентября 2011

Майк Эш уже реализовал класс таймера для этого.

Вам нужно инициировать его с типом поведения, в зависимости от того, какое именно поведение вы хотите:

  • MABGTimerDelay означает, что каждый раз, когда вы звоните afterDelay:1.0 do:^{ /*code*/ }, он сбрасывает дату срабатывания так, что он запускается только на целую секунду после последнего вызова.
  • MABGTimerCoalesce означает, что каждый раз, когда вы звоните afterDelay:1.0 do:^{ /*code*/ }, он устанавливает дату возгорания так, что он запускается только на целую секунду после первого вызова.

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

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

Когда поток завершает вызов метода в основном потоке. В этом методе сделайте таймер с задержкой в ​​1 секунду.

- (void)threadDidFinish
{
    if (_saveTimer != nil)
    {
        _saveTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(saveTimerDidFire) userInfo:nil repeats:NO];
    }
}

- (void)saveTimerDidFire
{
    [_saveTimer invalidate];
    _saveTimer = nil;

    // save the changes
}

Этот код гарантирует, что вы будете сохранять каждую секунду независимо от того, сколько раз был вызван threadDidFinish. NSTimer * _saveTimer является переменной экземпляра.

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

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

    BOOL needsUpdate;
    -(void) loop {
    if (needsUpdate) {
        //Run Block
        needsUpdate = NO;
    }
    [self performSelector:@selector(loop) withObject:nil afterDelay:1.0];
    }

Когда потоки заканчивают загрузку, вы просто устанавливаете needsUpdate = YES, а остальное позаботится о цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...