How to call a method every x seconds in Objective-C using NSTimer?

RoelfMik picture RoelfMik · Nov 19, 2012 · Viewed 48.7k times · Source

I am using Objective-C, Xcode 4.5.1 and working on an app for the iPhone.

I have a method A in which I want to call another method B to do a series of calculations every x seconds. In method A I start playing an audio file. Method B will monitor the audio every x seconds for the duration of the audio file.

I have found NSTimer as a potential solution, but am having a hard time getting it to work/understanding it.

I simply want to call Method B every x seconds and run its calculations, but NSTimer requires me to provide several things of which I'm not sure what I'm supposed to tell it.

[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval) 
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];

It is my understanding that at NSTimeInterval I provide the interval at which I want NSTimer to operate. But, how do I tell it to run Method B?

I have looked at example code, and am currently under the impression that I provide the method at the 'select:'. But, what do I write at the 'target:'? Why would I need a target? I tried entering 'self', but Xcode tells me:

Use of undeclared identifier 'self'

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self 
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];

So, I figure 'self' is supposed to be a pointer to an object, but where do I want to point to?

Below is a simplification of my code:

MethodA()
{
//Start playing an audio file.

//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}

MethodB()
{
//Do calculations.
}

I would be grateful if somebody could provide me with some answers/point me in the right direction! (:

Answer

Hermann Klecker picture Hermann Klecker · Nov 19, 2012

Target is the recipient of the message named in select. In Objective-C functions are not called. There are rather messages sent to objects. The Object internally refers to its symbol table and determines which of its methods is being called. That is a selector. Your selector is @selector(MethodB). (BTW: you should start method names with lower case. "methodB" would be more appropriate here.) This leads to the question: how to determine the object to which the message is sent? That is the target. In your case, it is simply self.

BTW: In this case the selector is expected to return void and accept an id, which is the id of the NSTimer object itself. That will come handy if you want the timer to stop firing based on some conditions according to your program logic. Most important: Your selector is then methodB: rather than 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.
}