Как я использую NSTimer?

Perl один лайнер, только для ударов:

perl -e '$s = shift; $SIG{ALRM} = sub { print STDERR "Timeout!\n"; kill INT => $p }; exec(@ARGV) unless $p = fork; alarm $s; waitpid $p, 0' 10 yes foo

Это печатает 'нечто' в течение десяти секунд, затем испытывает таймаут. Замените '10' любым числом секунд, и 'да нечто' с любой командой.

344
задан bmajz 8 November 2013 в 06:25
поделиться

3 ответа

Во-первых, я хотел бы обратить ваше внимание на документацию Cocoa / CF (которая всегда является отличным первым портом захода). В документации Apple есть раздел в верхней части каждой справочной статьи под названием «Дополнительные руководства», в котором перечислены руководства по документированной теме (если таковые существуют). Например, для NSTimer , в документации перечислены два сопутствующих руководства:

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

  • Таймеры
  • Использование таймеров

Для статей, которые принимают этот формат, часто есть обзор класса и того, для чего он используется, а затем некоторый пример кода , как его использовать, в данном случае в разделе «Использование таймеров». Есть разделы «Создание и планирование таймера», «Остановка таймера» и «Управление памятью». Из этой статьи создать запланированный неповторяющийся таймер можно примерно так:

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

Это создаст таймер, который запускается через 2,0 секунды и вызывает targetMethod: на self ] с одним аргументом, который является указателем на экземпляр NSTimer .

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

Если вы хотите остановить таймер, который повторяется, (или остановите неповторяющийся таймер до его срабатывания), тогда вам нужно сохранить указатель на созданный экземпляр NSTimer ; часто это должна быть переменная экземпляра, чтобы вы могли ссылаться на нее в другом методе. Затем вы можете вызвать invalidate в экземпляре NSTimer :

[myTimer invalidate];
myTimer = nil;

Также рекомендуется использовать nil из переменной экземпляра (например, если ваш метод делает недействительным таймер вызывается более одного раза, и для переменной экземпляра не установлено значение nil , а экземпляр NSTimer был освобожден, он вызовет исключение).

Обратите внимание также на пункт об управлении памятью в конце статьи:

Поскольку цикл выполнения поддерживает таймер, с точки зрения управления памятью там » Как правило, нет необходимости сохранять ссылку на таймер после того, как вы его запланировали . Поскольку таймер передается в качестве аргумента, когда вы указываете его метод в качестве селектора, вы можете аннулировать повторяющийся таймер, когда это необходимо в этом методе . Однако во многих ситуациях вам также может понадобиться опция отключения таймера - возможно, даже до его запуска. В этом случае вам нужно сохранить ссылку на таймер, чтобы вы могли отправить ему сообщение о недействительности, когда это необходимо . Если вы создаете незапланированный таймер (см. «Незапланированные таймеры»), вы должны поддерживать надежную ссылку на таймер (в среде с подсчетом ссылок вы сохраняете его), чтобы он не освобождался перед использованием.

616
ответ дан 23 November 2019 в 00:31
поделиться

Примерно так:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];
59
ответ дан 23 November 2019 в 00:31
поделиться

есть несколько способов использования таймера:

1) запланированный таймер и используя селектор

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • , если вы установите для повторов значение НЕТ, таймер подождет 2 секунды перед запуском селектора, а затем остановится;
  • if repeat: YES, таймер запустится немедленно и будет повторять вызов селектора каждые 2 секунды;
  • чтобы остановить таймер, вы вызываете метод таймера -invalidate: [t invalidate];

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

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

это будет иметь тот же эффект, что и пример кода выше; но если вы хотите вызывать селектор каждый n-й раз, вы используете таймер с повторами: YES; таймер запустится немедленно и будет повторять вызов селектора каждые 2 секунды;

  • чтобы остановить таймер, вы вызываете метод таймера -invalidate: [t invalidate];
  • В качестве дополнительного примечания вместо использования таймера, который не 'не повторять и вызывать селектор через заданный интервал, вы можете использовать простой оператор вроде этого:

    [self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
    

    это будет иметь тот же эффект, что и пример кода выше; но если вы хотите вызывать селектор каждый n-й раз, вы используете таймер с повторами: YES; таймер запустится немедленно и будет повторять вызов селектора каждые 2 секунды;

  • чтобы остановить таймер, вы вызываете метод таймера -invalidate: [t invalidate];
  • В качестве дополнительного примечания вместо использования таймера, который не 'не повторять и вызывать селектор через заданный интервал, вы можете использовать простой оператор вроде этого:

    [self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
    

    это будет иметь тот же эффект, что и пример кода выше; но если вы хотите вызывать селектор каждый n-й раз, вы используете таймер с повторами: YES;

    2) таймер с автоматическим планированием

    NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
    NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                                  interval: 1
                                  target: self
                                  selector:@selector(onTick:)
                                  userInfo:nil repeats:YES];
    
    NSRunLoop *runner = [NSRunLoop currentRunLoop];
    [runner addTimer:t forMode: NSDefaultRunLoopMode];
    [t release];
    
    • создает таймер, который запускается в заданную вами дату (в данном случае через минуту) и повторяется каждую секунду.

    3) незапланированный таймер и вызов

    NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
    [inv setTarget: self];
    [inv setSelector:@selector(onTick:)];
    
    NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                          invocation:inv 
                          repeats:YES];
    

    , после чего вы запускаете таймер вручную, когда вам нужно, вот так:

    NSRunLoop *runner = [NSRunLoop currentRunLoop];
    [runner addTimer: t forMode: NSDefaultRunLoopMode];
    



    И как примечание, метод onTick: выглядит так:

    -(void)onTick:(NSTimer *)timer {
       //do smth
    }
    
    331
    ответ дан 23 November 2019 в 00:31
    поделиться