23

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! (:

SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
RoelfMik
  • 255
  • 1
  • 2
  • 9

4 Answers4

43

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.
}
Hermann Klecker
  • 14,039
  • 5
  • 48
  • 71
  • Thank you for your answer! You were a great help! I managed to figure it all out! (: @Hermann Klecker – RoelfMik Nov 28 '12 at 13:26
  • You are welcome. If it was helpful eventaully I would not mind an 'accept' though. :) – Hermann Klecker Nov 28 '12 at 14:48
  • I am using the same code but the methodB is not getting called. Here's the code -(void)cardTimer{ NSLog(@"inside timer"); NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 3.0f target: self selector: @selector(timerCalled:) userInfo: nil repeats: NO]; [timersArray addObject:timer]; NSLog(@"timer called 1"); // getting logs till here } -(void)timerCalled:(NSTimer *)timer{ NSLog(@"Timer called 2"); isTooManyCard=false; [cards removeAllObjects]; [uniquePages removeAllObjects]; } – Ayush Malviya Aug 12 '19 at 12:23
6

try this

 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

}

}
NANNAV
  • 4,875
  • 4
  • 32
  • 50
5

Well you are trying to call an normal C method, NSTimer can't to that.

The target is the an instance of the class on which to call the selector, this selector adn not select. The selector here is a SEL type which you can create with the @selector(METHOD_NAME) function.

For example this will call the handleTimer : ever 0.1 second: (For this example the AppDelegate is used):

- (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.
}
rckoenes
  • 69,092
  • 8
  • 134
  • 166
5

If you look at your code and compared to the one below

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

self means that you are invoking a method in same instance of your class, in your example the method is myVolumeMonitor

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

and you are good to go though

method be should look like this

- (void)MethodB:(NSTimer*)timer { 
// do something
}
CodeBro
  • 209
  • 1
  • 4
  • Select is not part of the method `scheduledTimerWithTimeInterval`, also method names should start with a lower case. – rckoenes Nov 19 '12 at 13:26
  • Dunno, copied this from working apps source code. Ok, yes I changed selector to select while trying to bold my answer – CodeBro Nov 19 '12 at 13:28
  • The method you call in the example does not exist: [`scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:`](https://developer.apple.com/library/IOS/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/doc/uid/20000319-CHDDAEIA) this what the method should be. – rckoenes Nov 19 '12 at 13:30
  • Thank you for your answer! I managed to figure it all out! (: – RoelfMik Nov 28 '12 at 13:25