[英]Responding well to touches
我正在开发音乐应用,因此我真的不能批准任何延迟。
我正在使用心爱的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尝试将其删除。
所以那行不通,而且我有点无能为力,如果有人可以帮助我,我会很感激。
使用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之后不要处理其他任何事情。毕竟,您仅使用指针作为字典的键...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.