如何在 Cocoa 中运行 NSTimer 直到标志变量 ON
Posted
技术标签:
【中文标题】如何在 Cocoa 中运行 NSTimer 直到标志变量 ON【英文标题】:How to run NSTimer until flag variable ON in Cocoa 【发布时间】:2013-09-04 03:48:02 【问题描述】:我有一个问题:我想让 NSTimer 等到 FLAG 变量为 YES,如果 FLAG = YES,myTimer 将停止。我怎样才能做到这一点?我试过下面的代码:
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 没有运行。请给我任何建议。提前致谢
【问题讨论】:
您想在升旗后立即结束计时器吗?如果是这种情况,您可能需要一个每秒或 500 毫秒重复的计时器,并在每个脉冲上检查标志或持续时间是否为真。 @TimothyWalters:是的,我想在升旗后立即结束计时器。你能给我示例代码吗?非常感谢 尝试不使用计时器:***.com/questions/149646/… 【参考方案1】:为什么不使用键值观察来进行 FLAG 更改?将 flag 变量添加为您正在使用的类的属性:
@property(nonatomic, assign) BOOL flag;
为了避免在您的 .m 中出现重复位置:
#define kFooFlagKey @"flag"
覆盖 -setFlag:因此它符合 KVO:
-(void)setFlag:(BOOL)flag
if (_flag == flag)
return;
[self willChangeValueForKey:kFooFlagKey];
_flag = flag;
[self didChangeValueForKey:kFooFlagKey];
在类的初始值设定项中,添加 self 作为您要监控的键路径的观察者。在这种情况下,它将用于属性“flag”。
[self addObserver:self
forKeyPath:kFooFlagKey
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:NULL];
不要忘记删除类中的观察者'-dealloc:
[self removeObserver:self forKeyPath:kFooFlagKey];
创建重复触发的计时器(firingCallBack 是每次触发时调用的方法):
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0f
target:self
selector:@selector(firingCallBack)
userInfo:nil
repeats:YES];
实现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];
根据需要执行 -resetAll。当您通过访问器设置标志变量并且标志设置为YES时,它将被调用
【讨论】:
【参考方案2】: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];
【讨论】:
谢谢,但我不想使用 beginSheet。我想将其显示为 NSwindow?我该怎么做?【参考方案3】:您只需启动计时器(已安排)并使其以相对较高的频率重复,并在满足条件时停止。一个计时器可以充当两个计时器,如下所示:
- (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
【讨论】:
您可以使用两个计时器,或者同一个计时器并在调用时调用两个方法。我会补充我的答案。以上是关于如何在 Cocoa 中运行 NSTimer 直到标志变量 ON的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 暂停 NSTimer 直到滚动完成