0

行。我知道标题可能令人困惑。

我实现的逻辑是这样的。

  • 应用中有一个检测器(如自行车速度计 - 移动箭头)
  • 当用户点击开始扫描按钮时 - 第一个方法执行。
  • NowStartMovements 决定随机旋转和随机数停止
  • 检测器上有 1 到 10 个数字。
  • 到目前为止,一切都很好。
  • 以下代码没有错误。
  • 箭头完美移动并停在适当位置(随机决定)

  • 但问题是“我已经为动作实现了 for 循环”

  • 因此,在执行 for 循环时,不会启用用户交互。

我还添加了我已经实现的代码。


-(IBAction)ScanStart:(id)sender
{
btnScan.enabled=NO; stopThroughButtons=NO; shouldNeedleGoRightSide=YES; currentNeedleValue=1; nxtNeedleValue=2;
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(nowStartMovements) userInfo:nil repeats:NO];
}

-(void)nowStartMovements{
totalRotations=arc4random()%9; if(totalRotations<3) totalRotations+=3;
currentRotation=0;stopValue=arc4random()%11; if(stopValue<1)stopValue=1;
int totalMovements=(totalRotations-1)*10 + ( (totalRotations%2==0)?10-stopValue:stopValue ), i;
for(i=0;i<totalMovements;i++){
    if (stopThroughButtons) return;
    [NSThread detachNewThreadSelector:@selector(moveNeedle) toTarget:self withObject:nil];
    usleep(200000);
}
}

-(void)moveNeedle{
spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
double fromValue=[[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue];
double toValue=[[arrayOfFloatValues objectAtIndex:nxtNeedleValue-1] doubleValue];
spinAnimation.duration=0.2;
spinAnimation.fromValue=[NSNumber numberWithFloat:fromValue];
spinAnimation.toValue = [NSNumber numberWithFloat:toValue];
[imgNideel.layer addAnimation:spinAnimation forKey:@"spinAnimation"];
[NSThread detachNewThreadSelector:@selector(MoveActualNeedle) toTarget:self withObject:nil];
}

-(void)MoveActualNeedle{
if(shouldNeedleGoRightSide){        
    if(currentNeedleValue<9) { currentNeedleValue++; nxtNeedleValue++;}
    else { shouldNeedleGoRightSide=NO; currentNeedleValue=10; nxtNeedleValue=9;
}
    imgNideel.transform=CGAffineTransformMakeRotation([[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue]);
} else {
    if(currentNeedleValue>2){ currentNeedleValue--; nxtNeedleValue--;} 
    else { shouldNeedleGoRightSide=YES; currentNeedleValue=1; nxtNeedleValue=2;
}
    imgNideel.transform=CGAffineTransformMakeRotation([[arrayOfFloatValues objectAtIndex:currentNeedleValue-1] doubleValue]);
}   
}
4

2 回答 2

2

您将需要重写您的逻辑,因此是 Timer 正在睡觉,而不是 usleep。重写您的函数,以便可重复计时器的每次迭代都执行 for 循环中的操作。

问题是 for 循环在主线程上休眠。如果您使用计时器并将重复设置为“是”,那么这基本上会执行您正在执行的 for/sleep 模式。当你想停止它时,调用 [timer invalidate];

于 2009-09-23T20:35:10.193 回答
1

理想情况下,您会使用计时器来安排针的运动。现有代码的最快解决方案是:

  • StartScan,更改-scheduledTimerWithTimeInterval:-performSelectorInBackground:

  • nowStartMovements,更改-detachNewThreadSelector:-performSelectorOnMainThread:

这样,usleep发生在后台线程上,不会阻塞主线程。只要主线程被阻塞,UI就会被冻结。

于 2009-09-23T22:30:24.297 回答