很好地回应接触

时间:2012-05-18 12:30:34

标签: ios cocoa-touch audiounit touchesbegan glkit

我正在制作音乐应用,所以我无法真正批准任何一种语言。

我使用心爱的touchesBegan / Moved / Ended处理我的触摸。 一切进展顺利,我设法合成一个音调(使用AudioUnit)并在手指下显示一个发光(使用GLKit),如果有少于4-7个音符/触摸击中,一切正常与此同时,它变得疯狂,让应用程序陷入困境。

我明白了,因为我做了很多工作(使用GLKit界面和我为合成引擎制作的界面),我需要一种方法来修复它。

我的代码是这样构建的:



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for(UITouch *touch in touches)
    {
        CGPoint lePoint = [touch locationInView:self.view];


        doing some calculataions for synth engine.......
        actually making the sound avilable to play through the interface........

        then I start to create the sprite object for the glow
        attaching it to the nsarray of the shapes
        //rejoycing in the awesomness of the sound


        adding the touch to the active touches array


    }

}

我在touchesEnded中完全相反。

所以在我试图让它工作得更好的时候,我尝试使用GCD作为GLKit的东西,所以它会异步发生, 它工作正常,但有时候我会看到屏幕上留下一丝光芒,因为当touchesEnded试图移除它时,它不在阵列中。

所以这不起作用,我有点无能为力,如果有人可以帮助我感恩。

1 个答案:

答案 0 :(得分:0)

使用GCD,但请确保使用并发队列,以便同时提交所有触摸。如果您需要等待完成,请使用dispatch_apply,否则只是异步启动它们。

您无法在预定时取消阻止,因此您可能需要检查触摸是否已结束或取消,并立即返回该块。

例如,像......

for (UITouch *touch in touches) {
    NSValue *key = [NSValue valueWithPointer:(__bridge void*)touch];
    MyData *data = [dictionary objectForKey:key];
    // set whatever attributes you want in the data for this touch
    // You may want to have a cancel flag in there, so you can set it later...
    CGPoint touchPoint = [touch locationInView:self.view];
    dispatch_async(someConcurrentQueue, ^{
        // If only one thing to do, check the flag at beginning, if it is a long task
        // may want to check it periodically so you cancel as soon as possible.
        if (data.touchHasEnded) return;
    });

另一种方法是每次触摸都有一个队列。您可以在touchesBegan中创建调度队列,并在其上抛出任务。你可以让他们全部完成,或者可能只是在touchesEnd中取消其中一些。

例如,如果状态已经改变为其他状态,则可能没有意义处理其间的剩余触摸。

我已经完成了这样的线条平滑。

无论哪种方式,如果您正在进行密集处理,您应该让系统弄清楚如何管理它。只要确保您可以在适当时终止您正在做的事情。

确保将状态标记为已完成,并且在touchesEnd之后不要处理任何其他内容...毕竟,您只是使用指针作为字典的键...