2011-12-27 6 views
6

Sto lavorando alla mia prima app per iOS e ho eseguito il primo ostacolo per cui non sono riuscito a trovare una buona risposta.Obiettivo C e iOS: esecuzione di un timer? NSTimer/Threads/NSDate/etc

Il problema: ho un costume UIGestureRecognizer e avere tutto cablato in modo corretto, e posso eseguire il codice per ogni contatto nel @selector dopo il riconoscimento. Questo è andato bene per molte cose, ma è un po 'troppo di input per gli altri.

Il mio obiettivo: creare un timer che si attiva a un intervallo specificato per eseguire la logica e per poterlo annullare al momento i tocchi vengono annullati.

Perché sto chiedendo qui: ci sono molte possibilità di soluzioni, ma nessuna si è rivelata la migliore da implementare. Finora sembra che

  • performSelector (e alcune variazioni su questo)
  • NSThread
  • NSTimer
  • NSDate
  • Operation Code
  • Credo di avere trovato così alcuni altri ...

Da tutta la ricerca, una qualche forma di fare un filo sembra la strada da percorrere, ma sono in perdita a quale sarebbe meglio lavorare per questa situazione.

Un esempio di implementazione: uno NSPoint viene eseguito ogni 0,10 secondi e viene presa la distanza tra il punto precedente e quello attuale. [Prendendo la distanza tra ogni punto stava producendo risultati molto disordinati].

Il codice rilevante:

- (void)viewDidLoad { 
CUIVerticalSwipeHold *vSwipe = 
[[CUIVerticalSwipeHold alloc] 
initWithTarget:self 
action:@selector(touchHoldMove:)]; 
[self.view addGestureRecognizer:vSwipe]; 
[vSwipe requireGestureRecognizerToFail:doubleTap]; 
} 

... 

- (IBAction)touchHoldMove:(UIGestureRecognizer *)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) { 

    } 

    if (sender.state == UIGestureRecognizerStateBegan) { 

    } 

    //other stuff to do goes here 

} 

risposta

11

Utilizzare un NSTimer

Set è in questo modo:

theTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(yourMethodThatYouWantRunEachTimeTheTimerFires) userInfo:nil repeats:YES]; 

Poi, quando si vuole annullare, fare qualcosa di simile:

if ([theTimer isValid]) 
{ 
    [theTimer invalidate]; 
} 

Nota che nell'esempio precedente dovresti dichiarare l'istanza "theTimer" di NSTimer dove sarà disponibile per entrambi i metodi. Nell'esempio sopra, "0.5" significa che il timer scatterà due volte al secondo. Regolare secondo necessità.

+1

Nota: è consigliabile impostare il timer su zero dopo averlo invalidato: [il timer non è valido]; theTimer = nil; – Groot

1

Per ragioni di completezza, aggiungo il mio finale di esecuzione qui (non che questo sia il modo per farlo, ma qui va)

.h

@interface { 
    NSTimer *myTimer; 
} 

@property (nonatomic, retain) NSTimer *myTimer; 

.m

@synthesize myTimer; 

------------------------------------------- 

- (void)viewDidLoad { 
//Relevant snipet 
CUIVerticalSwipeHold *vSwipe = 
[[CUIVerticalSwipeHold alloc] 
initWithTarget:self 
action:@selector(touchHoldMove:)]; 
[self.view addGestureRecognizer:vSwipe]; 
[vSwipe requireGestureRecognizerToFail:doubleTap]; 
} 

------------------------------------------- 

- (IBAction)touchHoldMove:(UIGestureRecognizer *)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) { 
     //Cancel the timer when the gesture ends 
     if ([myTimer isValid]) 
      { 
       [myTimer invalidate]; 
      } 
     } 
    } 

    if (sender.state == UIGestureRecognizerStateBegan) { 
     //starting the timer when the gesture begins 
     myTimer = [NSTimer scheduledTimerWithTimeInterval:someTimeIncrement 
                target:self 
               selector:@selector(someSelector) 
               userInfo:nil 
                repeats:YES]; 
    } 
}