Как вызвать метод каждые x секунд в Objective-C с помощью NSTimer?
Я использую Objective-C, Xcode 4.5.1 и работаю над приложением для iPhone.
У меня есть метод A, в котором я хочу вызвать другой метод B для выполнения серии вычислений каждые x секунд. В методе A я начинаю воспроизведение аудиофайла. Метод B будет отслеживать звук каждые x секунд в течение продолжительности звукового файла.
Я нашел NSTimer
как потенциальное решение, но мне трудно заставить его работать/понимать его.
Я просто хочу вызвать метод B каждые х секунд и выполнить его вычисления, но NSTimer
требует, чтобы я предоставил несколько вещей, о которых я не уверен, что я должен сказать.
[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];
Я понимаю, что в NSTimeInterval
я предоставляю интервал, в который я хочу NSTimer
работать. Но, как я могу сказать, что он запускает метод B?
Я посмотрел пример кода, и в настоящее время создается впечатление, что я предоставляю метод в select:
. Но что я пишу на "target:
"? Зачем мне нужна цель? Я попытался ввести 'self
', но Xcode сообщает мне:
Использование незаявленного идентификатора 'self'
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
Итак, я полагаю, что 'self
' должен быть указателем на объект, но где я хочу указать?
Ниже приводится упрощение моего кода:
MethodA()
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}
MethodB()
{
//Do calculations.
}
Я был бы признателен, если бы кто-нибудь мог дать мне несколько ответов/указать мне в правильном направлении! (
Ответы
Ответ 1
Цель - получатель сообщения, указанного в select.
В Objective-C функции не вызываются. На объекты отправляются сообщения. Объект внутренне ссылается на свою таблицу символов и определяет, какой из его методов вызывается. Это селектор. Ваш селектор @selector(MethodB)
.
(Кстати: вы должны начинать имена методов в нижнем регистре. "MethodB" был бы более уместным.)
Это приводит к вопросу: как определить объект, которому отправлено сообщение? Это цель. В вашем случае это просто self
.
BTW: В этом случае ожидается, что селектор вернет void и примет идентификатор, который является идентификатором самого объекта NSTimer. Это будет удобно, если вы хотите, чтобы таймер прекратил стрельбу на основе некоторых условий в соответствии с вашей логикой программы.
Самое главное: ваш селектор тогда methodB:
, а не methodB
.
- (void) methodA
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every 5 seconds.
[NSTimer scheduledTimerWithTimeInterval:5.0f
target:self selector:@selector(methodB:) userInfo:nil repeats:YES];
}
- (void) methodB:(NSTimer *)timer
{
//Do calculations.
}
Ответ 2
Ну, вы пытаетесь вызвать обычный метод C, NSTimer
не может этого сделать.
Цель - это экземпляр класса, для которого вызывается селектор, этот селектор не выбирается. Селектором здесь является тип SEL
, который можно создать с помощью функции @selector(METHOD_NAME)
.
Например, это вызовет handleTimer :
каждые 0,1 секунды: (В этом примере используется AppDelegate):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//SNIP, some code to setup the windos.
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
return YES;
}
- (void) handleTimer:(NSTimer *)timer {
// Hanlde the timed event.
}
Ответ 3
Если вы посмотрите на свой код и сравните его с приведенным ниже
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
self означает, что вы вызываете метод в том же экземпляре вашего класса, в вашем примере метод myVolumeMonitor
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:@selector(MethodB) userInfo:nil repeats:YES];
и вам хорошо идти, хотя
метод должен выглядеть так:
- (void)MethodB:(NSTimer*)timer {
// do something
}
Ответ 4
попробуйте это
NSTimer *aTimer = [NSTimer timerWithTimeInterval:(x) target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:aTimer forMode: NSDefaultRunLoopMode];
[popUpImageView release];
- (void)timerFired:(NSTimer*)theTimer
{
if(condition)
{
[theTimer isValid]; //recall the NSTimer
//implement your methods
}
else
{
[theTimer invalidate]; //stop the NSTimer
}
}