Objective c 重置NSTimer';现在是开火时间,而不是最后一次开火
我有一个Objective c 重置NSTimer';现在是开火时间,而不是最后一次开火,objective-c,cocoa-touch,nstimer,Objective C,Cocoa Touch,Nstimer,我有一个NSTimer,它以3秒的间隔触发以减小值。当我执行增加该值的操作时,我希望重新启动计时器,从该点开始计数3秒 例如,如果我增加该值,计时器将在1秒内启动,我想更改该值,使计时器在3秒内启动。我可以使计时器失效并重新创建它吗?或者我可以使用setFireDate:,使用当前日期并添加3秒的间隔来执行此操作吗?是的,您可以使其无效。然后再创建一次 您还可以使用: - (void) myTimedTask { // other stuff this task needs to do
NSTimer
,它以3秒的间隔触发以减小值。当我执行增加该值的操作时,我希望重新启动计时器,从该点开始计数3秒
例如,如果我增加该值,计时器将在1秒内启动,我想更改该值,使计时器在3秒内启动。我可以使计时器失效并重新创建它吗?或者我可以使用
setFireDate:
,使用当前日期并添加3秒的间隔来执行此操作吗?是的,您可以使其无效。然后再创建一次
您还可以使用:
- (void) myTimedTask {
// other stuff this task needs to do
// change the variable varyingDelay to be 1s or 3s or... This can be an instance variable or global that is changed by other parts of your app
// weStillWantTimer is also a similar variable that your app uses to stop this recurring task
if (weStillWantTimer)
[self performSelector:@selector(myTimedTask:) withObject:gameColor afterDelay:varyingDelay];
}
您可以调用myTimedTask来启动定期任务。启动后,您可以使用varyingDelay更改延迟,或使用weStillWantTimer停止延迟。使计时器无效并重新创建它。但是,请确保不使计时器失效并释放计时器,除非您确定需要,因为运行循环会保留计时器,直到计时器失效,然后自行释放计时器
在我看来,将-performSelector代码与计时器代码混合使用会导致目标方法的多次执行,因此我不想这样做。是的,使计时器无效并重新创建它会起作用。如果你不增加你的价值,这基本上就是你想要做的:重置并重新开始。文件提到更改启动日期相对昂贵,建议最好销毁并重新创建计时器,除非你经常这么做。然而,为了便于讨论,我不久前突然提出了这一类别。我更喜欢这个,因为它封装了日期调整行为;计时器本身处理它,而不是它的所有者/控制器。不过,我没有这方面的任何性能数据
@implementation NSTimer (WSSAdjustingFireDate)
- (void)WSSFireAdjustingFireDate
{
[self fire];
[self WSSSkipNextFireAdjustingFireDate];
}
- (void)WSSSkipNextFireAdjustingFireDate
{
CFRunLoopTimerRef cfSelf = (__bridge CFRunLoopTimerRef)self;
CFTimeInterval delay = CFRunLoopTimerGetInterval(cfSelf);
CFRunLoopTimerSetNextFireDate(cfSelf, CFAbsoluteTimeGetCurrent() + delay);
}
@end
我使用了核心基础函数,只是为了避免创建<代码> NSDATE < /代码>。过早优化?请通过测试。
我做了一些测试,结果表明,重置fireDate比使计时器失效和重新创建计时器快四倍左右。首先,我创建了一个计时器,它调用方法doNothing:if (!testTimer) {
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(doNothing:)
userInfo:nil
repeats:NO];
testTimer = timer;
}
以下是测试代码:
- (void) testInvalidatingTimer {
for (int n = 0; n < 10000; n++) {
[testTimer invalidate];
testTimer = nil;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(doNothing:)
userInfo:nil
repeats:NO];
testTimer = timer;
}
}
- (void) testResettingTimer {
for (int n = 0; n < 10000; n++) {
if ([testTimer isValid]) {
testTimer.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
}
}
}
-(无效)测试验证计时器{
对于(int n=0;n<10000;n++){
[testTimer invalidate];
testTimer=nil;
NSTimer*定时器=[NSTimer scheduledTimerWithTimeInterval:3.0
目标:自我
选择器:@selector(不带任何内容:)
用户信息:无
重复:否];
testTimer=计时器;
}
}
-(无效)测试重置计时器{
对于(int n=0;n<10000;n++){
如果([testTimer isValid]){
testTimer.fireDate=[nsdatedatewithtimeintervalsincenow:3.0];
}
}
}
在iPad Air上运行该程序,失效计时器的时间为0.198173秒,重置计时器的时间为0.044207秒。如果性能是您的目标,我建议重置fireDate。这也大大减少了编码工作量。@zoul,这取决于您想要的混乱程度:-)最后,我使用setFireWithDate,当我增加值时,我还会向计时器发送一条消息,当前日期加上三秒。很有效^^非常感谢。