views:

969

answers:

1

Hi all,

I've implemented a tap-and-hold handler using an NSTimer that I first set in the TouchesBegan overload.

However, what I actually want is for an action to be continuously performed in quick-fire succession while the touch is being held. So, on timer expiry I call a handler to do the work, which then sets another timer and the cycle continues until the TouchesEnded comes in and cancels it, or another terminating condition is met.

This works fine, until my handler code triggers an animation to go off at the same time. Now we have animation events and timer events going off, and in all that we need to handle TouchesEnded as well.

What I am finding is that, if the animation is triggered, and I set my timer to less than 0.025 seconds, my TouchesEnded event doesn't come through until the timer cycle stops (the other terminating condition). Setting a slower timer, or not triggering the animation, make it work (TouchedEnded comes in straight away), but are not what I want.

Obviously this is all on the device (release build - no NSLogs) - in the sim it all works fine

Is there any way of setting the relative priorty of these events - or is it likely I'm missing something else obvious here?

[Update]

I've worked around this in this instance by doing the continuous part without visual feedback until it's done (which from this users perspective is instant). I think this is ok for now. I'd still like to hear any more thoughts on this (Jeffrey's idea was good), but I'm not waiting on tenterhooks now.

+1  A: 

Try writing your own Timer-type class by spawning off onto a thread. Example:

BOOL continue = YES; //outside of your @implementation

-(void)doLoop
{
   while(continue){
      [NSThread sleepForTimeInterval:.025];
      [self performSelectorOnMainThread:@selector(whateverTheFunctionIs) waitUntilDone:YES];
    }
}

and this would be started by [NSThread detatchNewThreadSelector:@selector(doLoop) toTarget:self withObject:nil]. This is not exactly threadsafe, but you can choose to wrap the boolean into a NSNumber and then do @synchronize on it if you so choose. Alternatively, after I wrote that little snippet I realized it would be better to do a check against the current NSTime instead of sleepForTimeInterval: but you get the point. :)

Jeffrey Forbes
Thanks Jeffrey. I'm not sure if that's the answer I'm looking for, but it's certainly something worth trying, and I could have some control over the priority that way - although still not so for the animation. Leaving this open for the moment - but thanks for the reply (and voted you up).
Phil Nash