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' любым числом секунд, и 'да нечто' с любой командой.
Во-первых, я хотел бы обратить ваше внимание на документацию 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
был освобожден, он вызовет исключение).
Обратите внимание также на пункт об управлении памятью в конце статьи:
Поскольку цикл выполнения поддерживает таймер, с точки зрения управления памятью там » Как правило, нет необходимости сохранять ссылку на таймер после того, как вы его запланировали . Поскольку таймер передается в качестве аргумента, когда вы указываете его метод в качестве селектора, вы можете аннулировать повторяющийся таймер, когда это необходимо в этом методе . Однако во многих ситуациях вам также может понадобиться опция отключения таймера - возможно, даже до его запуска. В этом случае вам нужно сохранить ссылку на таймер, чтобы вы могли отправить ему сообщение о недействительности, когда это необходимо . Если вы создаете незапланированный таймер (см. «Незапланированные таймеры»), вы должны поддерживать надежную ссылку на таймер (в среде с подсчетом ссылок вы сохраняете его), чтобы он не освобождался перед использованием.
Примерно так:
NSTimer *timer;
timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: @selector(handleTimer:)
userInfo: nil
repeats: YES];
есть несколько способов использования таймера:
1) запланированный таймер и используя селектор
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(onTick:)
userInfo: nil repeats:NO];
В качестве дополнительного примечания , вместо использования таймера, который не повторяется и вызывает селектор через заданный интервал, вы можете использовать простую инструкцию вроде этого:
[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
это будет иметь тот же эффект, что и пример кода выше; но если вы хотите вызывать селектор каждый n-й раз, вы используете таймер с повторами: YES; таймер запустится немедленно и будет повторять вызов селектора каждые 2 секунды;
В качестве дополнительного примечания вместо использования таймера, который не 'не повторять и вызывать селектор через заданный интервал, вы можете использовать простой оператор вроде этого:
[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
это будет иметь тот же эффект, что и пример кода выше; но если вы хотите вызывать селектор каждый n-й раз, вы используете таймер с повторами: YES; таймер запустится немедленно и будет повторять вызов селектора каждые 2 секунды;
В качестве дополнительного примечания вместо использования таймера, который не 'не повторять и вызывать селектор через заданный интервал, вы можете использовать простой оператор вроде этого:
[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
}