iOS音序器速度滑块导致应用程序崩溃

时间:2016-04-19 15:16:39

标签: ios objective-c audio slider

我使用Objective C创建了一个鼓音序器。我希望滑块控制速度。目前,一切正常,每个步骤之间的间隔由以下方式控制:

 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];
        }

所以每步之间的时间是0.2秒。我试图在视图控制器.m中实现这样的速度滑块(滑块的范围为0.3到1.0,因此将输出与当前时间类似的值):

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

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

并将while(self.running)线程中的行更改为:

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

但是,这会导致步骤之间的时间太短(速度很快),当触摸应用程序中的任何控件时,它会崩溃。

我想知道是否需要设置这样的功能,但我不确定内部会有什么能使速度滑块工作:

- (void)setTempo:(float)tempo
{

}

我试图尽可能清楚,如果有人能帮助我,我将非常感激,提前谢谢

2 个答案:

答案 0 :(得分: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
}

下面是使用GCD进行异步线程管理的示例

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!!!";
    });
});

希望有所帮助

答案 1 :(得分:1)

Luca对使用GCD是正确的。如果谈谈你的初步解决方案。 你为_tempo设定了初始值吗?看起来你的bug最初可能是由_tempo = 0引起的。如您所知,只有在一些用户操作后才会调用sliderMoved,因此您需要设置初始值。