2016-04-19 9 views
0

Ich habe einen Drum-Sequenzer mit Objective C erstellt. Ich möchte den Schieberegler, um das Tempo zu steuern. Im Moment funktioniert alles, und das Intervall zwischen jedem Schritt kontrolliert wird:iOS Sequenzer Tempo-Schieberegler verursacht App zum Absturz

while (self.running) 
     { 
      // sleep until the next step is due 
      [NSThread sleepUntilDate:time]; 

      // update step 
      int step = self.step + 1; 

      // wrap around if we reached NUMSTEPS 
      if (step >= NUMSTEPS) 
       step = 0; 

      // store 
      self.step = step; 

      // time duration until next step 
      time = [time dateByAddingTimeInterval:0.2]; 
     } 

zwischen jedem Schritt also die Zeit beträgt 0,2 Sekunden. Ich habe versucht, einen Temporegler wie so im View-Controller .m zu implementieren (der Schieber hat einen Bereich von 0,3 bis 1,0 wird so ausgegeben ähnlicher Wert zu dem, was in der Zeit ist zur Zeit):

- (IBAction)sliderMoved:(UISlider *)sender 
    { 

     AppDelegate* app = [[UIApplication sharedApplication] delegate]; 
     app.tempo = sender.value; 
    } 

und durch die sie wandelnde Linie in der while (self.running) Thread zu:

time = [time dateByAddingTimeInterval: (NSTimeInterval) _tempo]; 

dies ist jedoch die Zeit zwischen den Schritten verursacht viel zu kurz sein (das Tempo ist verrückt schnell) und wenn eine Kontrolle in der App berührt wird, stürzt .

Ich frage mich, ob ich eine Funktion wie diese einrichten müssen, aber ich bin mir nicht sicher, was im Inneren gehen würde den Temporegler zu ermöglichen, zu arbeiten:

- (void)setTempo:(float)tempo 
{ 

} 

habe ich versucht, so klar zu sein, wie ich kann, wenn mir jemand helfen kann, wäre ich sehr dankbar, danke im voraus

+1

Wenden Sie die Verzögerung auf einen separaten Thread an, der sich vom Hauptthread unterscheidet? –

+0

Nein, ich denke nicht, es ist im Hauptthread – Neo

+0

Das ist schlecht, nicht nur für iOS, aber im Allgemeinen, diese Art von Aktion, die Sperrvorgang erwarten (in Ihrem Fall, dass Verzögerung) sollte in anderen asynchronen Thread ausgeführt werden. In iOS können Sie GCD (dispatches) oder NSOperation, NSOperationQueue und NSTimer nutzen. In Ihrem Fall könnte der NSTimer die beste Lösung für Sie sein. Ich versuche zu schreiben als mögliche Lösung als Antwort unter –

Antwort

1
-(void) startDrumTick{ 
    [self.myDrumTimer invalidate]; // stop any current existing timer 

    // perform the call to the method 'drumMethodOperation:' 
    // every 0.2 sec. NB: drumMethodOperation will run on main thread. 
    // this means that if you expect to do long-blocking operation, 
    // you will need to move that op to an async thread, in order to avoid 
    // the UI blocking 

    self.myDrumTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 
          target:self 
          selector:@selector(drumMethodOperation:) 
          userInfo:nil 
          repeats:YES];   
} 

-(void)drumMethodOperation:(id)sender 
{ 
    // update step 
    int step = self.step + 1; 

    // wrap around if we reached NUMSTEPS 
    if (step >= NUMSTEPS) 
     step = 0; 

    // store 
    self.step = step; 

    // any other needed operation to run every 0.2 secs 
} 

im Folgenden ein Beispiel für ein asynchrones Thread-Management GCD mit

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ 

    // Long blocking operation (DO NOT PERFORM ANY UI OPERATION, like changing a text label, setting an image to an UIImageView, etc.) 

    [self myLongDbQuery]; 

    dispatch_async(dispatch_get_main_queue(), ^(void){ 
     //Perform you UI Updates here 
     self.myLabel.text = @"Query done!!!"; 
    }); 
}); 

Hoffe, es hilft

1

Luca hat Recht über die Verwendung von GCD. Sprechen Sie über Ihre ursprüngliche Lösung. Haben Sie den Anfangswert für _tempo festgelegt? Sieht so aus, als ob dein Fehler durch _tempo = 0 verursacht werden kann. Wie Sie wissen, wird sliderMoved erst nach einer Benutzeraktion aufgerufen, so dass Sie den Anfangswert festlegen müssen.

+0

_tempo ist so erklärt, so bin ich mir nicht sicher. Aber der Min Slider Wert ist 0,3, also sehe ich nicht, wie es ein Problem ist? @ synthesize tempo = _tempo; – Neo

+0

Problem ist, dass Sie Wert nur in dieser Aktion setzen - (IBAction) sliderMoved: (UISlider *) Absender , die nur nach Benutzer Änderung Schieberegler Wert aufgerufen. Daher müssen Sie den initialen _tempo Wert während der Initialisierung angeben. –

Verwandte Themen