Objective c 如何在Cocoa中运行NSTimer直到打开标志变量

Objective c 如何在Cocoa中运行NSTimer直到打开标志变量,objective-c,macos,cocoa,nstimer,Objective C,Macos,Cocoa,Nstimer,我有一个问题:我想在FLAG变量为YES时停止计时,如果FLAG=YES,则myTimer为stop。我该怎么做?我尝试了以下代码: NSTimer *myTimer; int delay = 6.0; scanTimer= [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:@selector(anotherfunc) userInfo:nil repeats:YES]; myTimer= [NSTimer time

我有一个问题:我想在FLAG变量为YES时停止计时,如果FLAG=YES,则myTimer为stop。我该怎么做?我尝试了以下代码:

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];
这是resetAll()函数:

-(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];
    }

}
我使用了2个NSTimer,但只有myTimer运行,scanTimer未运行。请给我一些建议。提前感谢

您只需启动计时器(已计划),并以相对较高的频率重复,并在满足条件时停止。一个计时器可以充当两个计时器,如下所示:

- (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
}
您只需启动计时器(已经安排好),并以相对较高的频率重复计时器,然后在满足条件时停止计时器。一个计时器可以充当两个计时器,如下所示:

- (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
}

为什么不使用键值来更改标志?将标志变量添加为您正在使用的类的属性:

@property(nonatomic, assign) BOOL flag;
要避免重复,请在.m中放置:

#define kFooFlagKey @"flag"
Override-setFlag:因此它符合KVO:

-(void)setFlag:(BOOL)flag
{
    if (_flag == flag) {
        return;
    }
    [self willChangeValueForKey:kFooFlagKey];
    _flag = flag;
    [self didChangeValueForKey:kFooFlagKey];
}
在类的初始值设定项中,添加self作为要监视的键路径的观察者。在这种情况下,它将用于属性“flag”

不要忘记删除类'-dealoc:

[self removeObserver:self forKeyPath:kFooFlagKey];
创建计时器以重复激发(firingCallBack是每次激发时调用的方法):

实施KVO观测方法:

-(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];
        }
    }
}

执行-根据需要重置所有内容。当您通过访问器设置标志变量且标志设置为“是”时,将调用该函数。为什么不使用键值来观察标志更改?将标志变量添加为您正在使用的类的属性:

@property(nonatomic, assign) BOOL flag;
要避免重复,请在.m中放置:

#define kFooFlagKey @"flag"
Override-setFlag:因此它符合KVO:

-(void)setFlag:(BOOL)flag
{
    if (_flag == flag) {
        return;
    }
    [self willChangeValueForKey:kFooFlagKey];
    _flag = flag;
    [self didChangeValueForKey:kFooFlagKey];
}
在类的初始值设定项中,添加self作为要监视的键路径的观察者。在这种情况下,它将用于属性“flag”

不要忘记删除类'-dealoc:

[self removeObserver:self forKeyPath:kFooFlagKey];
创建计时器以重复激发(firingCallBack是每次激发时调用的方法):

实施KVO观测方法:

-(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];
        }
    }
}

执行-根据需要重置所有内容。当您通过访问器设置标志变量且标志设置为YES(是)时,将调用该函数。您想在标志升起后立即结束计时器吗?如果是这种情况,您可能需要一个每秒或500毫秒重复一次的计时器,并在每次脉冲检查时检查标志或持续时间是否为真。@TimothyWalters:是的,我想在标志升起时尽快结束计时器。你能给我举个例子吗?非常感谢没有计时器:你想在国旗升起后立即结束计时器吗?如果是这种情况,您可能需要一个每秒或500毫秒重复一次的计时器,并在每次脉冲检查时检查标志或持续时间是否为真。@TimothyWalters:是的,我想在标志升起时尽快结束计时器。你能给我举个例子吗?非常感谢不用定时器:您可以使用两个定时器,或者使用同一个定时器并在调用时调用两个方法。我将添加到我的答案中。您可以使用两个计时器,或者使用同一个计时器并在调用时调用两个方法。我将补充我的答案。谢谢,但我不想使用beginSheet。我想把它显示为一个窗口?我怎么做?谢谢,但我不想用beginSheet。我想把它显示为一个窗口?我该怎么做?