10

I have an NSTimer that should call a method every second, but it doesn't seem to be calling it at all.

This is how I declare the timer:

[NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(fadeManager:) userInfo:nil repeats:YES];

This is the method it calls:

-(void) fadeManager: (NSTimer*) timer{
    NSLog(@"IT'S WORKING!");
    self.playHead += .1; // keeps track of where they are in full track
    if (self.playHead >= self.wait  && ![player isPlaying]) { // checks if wait is over
        [player play];
    }
    if (self.playHead >= self.duration + self.startTime && [player isPlaying]) { // checks if full duration is over
        [player pause];
        [self reset];
    }
    int fadeOutArea = self.startTime + self.duration - self.fadeOut;
    int fadeInArea = self.startTime + self.fadeIn;
    if (self.playHead <= fadeInArea && [player volume] < relativeVolume) { // checks if fadingIn.
        [self fadeInIncriment];
    }
    if (self.playHead >= fadeOutArea  && [player volume] > 0) {
        [self fadeOutIncriment];
    }
}

The code was not working so I put the NSLog in as well as a break point. It seems that it is never being called. Why is this? Does it matter that I declared the method in the .m file like this:

#import <AVFoundation/AVFoundation.h>
@interface CueMusic ()

- (void) delayFadeOut: (AVAudioPlayer*) dFade;
- (void) fadeInIncriment;
- (void) fadeOutIncriment;
- (void) fadeManager: (NSTimer*) timer; // <--------
- (void) start;

@end

@implementation CueMusic
 .......
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
sinθ
  • 11,093
  • 25
  • 85
  • 121

4 Answers4

23

Either use

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(fadeManager:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

or

//schedules the timer
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fadeManager:) userInfo:nil repeats:YES];

From the docs Scheduling Timers in Run Loops


Swift Code

Either

let timer: NSTimer = NSTimer(timeInterval: 1.0, target: self, selector: "fadeManager:", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)

Or

//schedules the timer
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "fadeManager:", userInfo: nil, repeats: true)
Community
  • 1
  • 1
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
6

Your problem is that when using timerWithTimeInterval:target:selector:userInfo:repeats:, the resulting timer does not automatically get added to the run loop. I would recommend using scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: instead, which performs this step for you.

If you prefer to use timerWithTimeInterval:target:selector:userInfo:repeats: then you need to manually add the timer to the current run loop. To do this, call NSRunLoop's addTimer:forMode: method. Documentation

[[NSRunLoop currentRunLoop] addTimer:tTimer forMode: NSDefaultRunLoopMode];
FreeAsInBeer
  • 12,937
  • 5
  • 50
  • 82
2

You need to fire the timer.

You can do it by adding it to a thread:

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(fadeManager:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

or calling

[timer fire];
pdrcabrod
  • 1,467
  • 1
  • 14
  • 22
1

You can use:

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140