0

My app adds a custom SKNode object to a SKScene at a fixed interval (sub second) using an NSTimer. At certain times I want the timer to speed up. Here's what I do (code simplified):

@interface MyScene : SKScene
@end

@implementation MyScene {
    MyNode *node;
    NSTimer *timer;
    int speed;
}

- (id):initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {
        speed = 0.8f;
        timer = [NSTimer = scheduledTimerWithTimeInterval:speed target:self selector:@selector(addNodeToScene) userInfo:nil repeats:YES];
    }
}

- (id):addNodeToScene {
    if (node != nil) {
        [node removeFromParent];
        node = nil;
    }

    CGPoint location = //random x y coordinates using arc4random()...

    node = [[MyNode alloc] initAtLocation:location];
    [self addChild:node];
}

// at some point I call this method (called regularly throughout life of app)
- (id):speedUp {
    [timer invalidate];
    timer = nil;
    speed *= 0.9f;
    timer = [NSTimer = scheduledTimerWithTimeInterval:speed target:self selector:@selector(addNodeToScene) userInfo:nil repeats:YES];
}

I've noticed a slight lag every time i call speedUp. I'm very new to Objective-C so not sure how to resolve. Is it more efficient to use dispatch queues over a timer or can I not avoid this issue because the internal is so fast?

I ran time profiling on instruments and this was not highlighted - instead my heaviest method was addNodeToScene.

Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
clicky
  • 865
  • 2
  • 14
  • 31

2 Answers2

2

My guess is that you're calling -speedUp outside of the normal work in -addNodeToScene. If so, the lag is likely coming from the fact that you've already used up a bit of the previous delay, then -speedUp invalidates the old timer and creates a new one, which starts the delay all over again. You'll see a lag any time you're more than 10% beyond the previous timer fire.

I'll try some ASCII art to illustrate. + is a timer fire, * is when you call -speedUp and it resets the timer.

+---------+--------+---------+---------+---------+
+---------+---*--------+--------+--------+--------+
Steve Madsen
  • 13,465
  • 4
  • 49
  • 67
0

Found the solution in another question: Xcode / Objective-C: Why is NSTimer sometimes slow/choppy?

(use CADisplayLink instead of NSTimer)

Community
  • 1
  • 1
clicky
  • 865
  • 2
  • 14
  • 31
  • That maybe the source of some lag, but `CADisplayLink` is tied to the screen refresh rate. I'm skeptical that it will work well for what you describe, where you're scaling your timer interval down in some steps. – Steve Madsen Jul 12 '14 at 15:57