我正在制作音乐应用,所以我无法真正批准任何一种语言。
我使用心爱的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试图移除它时,它不在阵列中。
所以这不起作用,我有点无能为力,如果有人可以帮助我感恩。
答案 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之后不要处理任何其他内容...毕竟,您只是使用指针作为字典的键...