0

I have a problem: I want to NSTimer waiting until FLAG variable is YES, if FLAG = YES, myTimer is stop. How can i do that? I tried below code:

NSTimer *myTimer;
int delay = 6.0;
scanTimer= [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:@selector(anotherfunc) userInfo:nil repeats:YES];
myTimer= [NSTimer timerWithTimeInterval: delay
                                         target:self
                                       selector: @selector(resetAll:) userInfo:nil
                                        repeats:NO];
        [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSModalPanelRunLoopMode];
        [[NSApplication sharedApplication] runModalForWindow: scanningPanel];

This is resetAll () function :

-(void) resetAll: (NSTimer *) theTimer
{
    if(FLAG)
    {
        NSLog(@"killWindow");
        [[NSApplication sharedApplication] abortModal];
        [scanningPanel orderOut: nil];
        FLAG = NO;
    }
    else
    {
        delay +=6.0;
        myTimer= [NSTimer timerWithTimeInterval: delay
                                         target:self
                                       selector: @selector(resetAll:) userInfo:nil
                                        repeats:NO];
        [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSModalPanelRunLoopMode];
        [[NSApplication sharedApplication] runModalForWindow: scanningPanel];
    }

}

I used 2 NSTimer, but only myTimer run, scanTimer not run. Please give me any suggestions. Thanks in advance

Joson Daniel
  • 409
  • 1
  • 9
  • 18
  • You want to end the timer as soon as the flag is raised? If that is the case you might want a timer that repeats every second or 500ms, and on each pulse check for either the flag or the duration being true. – Timothy Walters Sep 04 '13 at 03:55
  • @TimothyWalters: Yes, i want to end timer as soon ass when the flag is raised. Can you example code to me? Thanks so much – Joson Daniel Sep 04 '13 at 03:58
  • try without timer: http://stackoverflow.com/questions/149646/best-way-to-make-nsrunloop-wait-for-a-flag-to-be-set – stosha Sep 04 '13 at 04:08

3 Answers3

3

Why not use Key Value Observing for the FLAG change? Add the flag variable as a property of the class you're working in:

@property(nonatomic, assign) BOOL flag;

To avoid repetition place in your .m:

#define kFooFlagKey @"flag"

Override -setFlag: so it is KVO compliant:

-(void)setFlag:(BOOL)flag
{
    if (_flag == flag) {
        return;
    }
    [self willChangeValueForKey:kFooFlagKey];
    _flag = flag;
    [self didChangeValueForKey:kFooFlagKey];
}

In the class' initializer add self as the observer for the keypath you'd like to monitor. In this case it will be for the property "flag".

[self addObserver:self
   forKeyPath:kFooFlagKey
      options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
      context:NULL];

Don't forget to remove the observer in the class' -dealloc:

[self removeObserver:self forKeyPath:kFooFlagKey];

Create the timer to fire repeatedly (firingCallBack is a method called with each fire):

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0f
                                                  target:self
                                                selector:@selector(firingCallBack)
                                                userInfo:nil
                                                 repeats:YES];

Implement KVO observing method:

-(void)observeValueForKeyPath:(NSString *)keyPath
                 ofObject:(id)object
                   change:(NSDictionary *)change
                  context:(void *)context
{
    if ([keyPath isEqualToString:kFooFlagKey]) {
        if (self.flag) {
           [self performSelector:@selector(resetAll) withObject:nil afterDelay:0.0f];
        }
    }
}

Implement -resetAll however you'd like. It will be called when you are setting the flag variable via the accessor AND the flag is set to YES

Brian Palma
  • 641
  • 1
  • 7
  • 13
1

You just start the timer (already scheduled) and make it repeat at a relatively high frequency and stop it when the condition is met. One timer can act as two, like this:

- (void)startTimers {

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];
}

- (void)timerFired:(NSTimer *)timer {

    if (self.stopTimerA && self.stopTimerB) {
        [timer invalidate];
    } else {
        if (!self.stopTimerA)
            [self timerAFired];
        if (!self.stopTimerB)
            [self timerBFired];
    }
}

- (void)timerAFired {
    // this can be coded like it has it's own timer
    // we didn't pass the timer, so we can't invalidate it
    // to stop...
    self.stopTimerA = YES;
}

- (void)timerBFired {
    // same idea here
}
danh
  • 62,181
  • 10
  • 95
  • 136
  • You can use two timers, or the same timer and call two methods on the invocation. I'll add to my answer. – danh Sep 04 '13 at 04:52
1
Try like this:-

NSTimer *myTimer;
int delay = 6.0;
scanTimer= [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:@selector(anotherfunc) userInfo:nil repeats:YES];
myTimer= [NSTimer scheduledTimerWithTimeInterval: delay
                                         target:self
                                       selector: @selector(resetAll:) userInfo:nil
                                        repeats:NO];
[NSApp beginSheet:scanningPanel modalForWindow:[self window]
        modalDelegate:self
       didEndSelector:nil
          contextInfo:self];

- (void)resetAll:(NSTimer *)theTimer
{
    if (flag== YES)
    {
    [NSApp endSheet:scanningPanel];
    [scanningPanel orderOut:self];
        flag=NO;
    }
    else
    {
   delay +=6.0;
myTimer= [NSTimer scheduledTimerWithTimeInterval: delay
                                         target:self
                                       selector: @selector(resetAll:) userInfo:nil
                                        repeats:NO];
    [NSApp beginSheet:scanningPanel modalForWindow:[self window]
        modalDelegate:self
       didEndSelector:nil
          contextInfo:self];
    }
}
Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56