0

我正在开发一个音乐应用程序,所以我真的不能批准任何延迟。

我正在使用心爱的 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 试图删除它。

所以这没有用,我有点无能为力,如果有人能帮助我,我会很感激。

4

1 回答 1

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 之后不处理任何其他内容...毕竟,您只是使用指针作为字典的键...

于 2012-05-18T22:51:43.950 回答