我有一个NSTimer
与3秒的时间间隔触发以减小的值。 当我这样做会增加值的行动,我要重新启动计时器从该点计数3秒。
例如,如果我增加1秒值和计时器将大火,我想改变这种状况,使计时器火灾在3秒内代替。 我可以无效计时器并重新创建它? 或者,我能和做setFireDate:
使用当前的日期和加入的3秒的时间间隔?
我有一个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停止。
我做了一个小测试,事实证明,重置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];
}
}
}
运行在iPad上的空气产生0.198173 S表示invalidatingTimer和0.044207 S代表resettingTimer。 如果性能是你的目标,我建议重置fireDate。 这也是相当少一点的编码工作。
无效计时器并重新创建它。 但是,请确保你没有失效并释放计时器,除非你确信你需要自运行循环保留计时器,直到它们无效,然后将其释放本身。
在我看来,混合-performSelector代码计时器代码导致的目标方法执行多次,所以我就留下来从远。
是的,无效并重新创建计时器。 它本质上是你想要做的,如果你不增加你的价值是什么:重置并重新启动。
该setFireDate:
文档提到,改变火日期是相对昂贵,这表明它可能是更好的破坏并重新创建计时器,除非你这样做了很多 。 为了讨论的方便,但是,我前阵子掀起这一类。 我喜欢这一点,因为它封装日期调整行为; 计时器本身处理它,而不是它的所有者/控制器。 我没有任何这性能数据,但。
@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
。 过早的优化? 请把盐递过来。