为什么只有一个我的 NSTimer 工作?
Why does only one of my NSTimers work?
我不明白为什么只有 animateDarkAst 动画有效。前两个计时器(一个在 processKeys 上运行的计时器和一个在 animateDarkAst 上运行的计时器)工作正常,但其他计时器则没有。我编写定时器的顺序无关紧要,只有这两种方法适用于各自的定时器。对于其他 3 个动画,屏幕上没有显示任何内容,因为它们的方法(animateLightAst、animateSmallAst、animateComet)中没有处理任何代码。
// Prepare asteroids.
_asteroiddark = [[NSImageView alloc] init];
[_asteroiddark setImage: [NSImage imageNamed:@"asteroiddark"]];
[_asteroiddark setFrame: theModel.darkAstRect];
_asteroidlight = [[NSImageView alloc] init];
[_asteroidlight setImage: [NSImage imageNamed:@"asteroidwhite"]];
[_asteroidlight setFrame: theModel.lightAstRect];
_asteroidsmall = [[NSImageView alloc] init];
[_asteroidsmall setImage: [NSImage imageNamed:@"asteroidsmall"]];
[_asteroidsmall setFrame: theModel.smallAstRect];
// ... and comets
_comet = [[NSImageView alloc] init];
[_comet setImage:[NSImage imageNamed:@"comet"]];
[_comet setFrame: theModel.cometRect];
// Set up key Processing timer for fluid spaceship movement.
timer1 = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(processKeys) userInfo:nil repeats:YES];
// Make a random value for first animation timer.
double randomInterval1 = arc4random() % (4 - 1) + 1;
// Set up key Processing timer for animation.
timer2 = [NSTimer scheduledTimerWithTimeInterval:randomInterval1 target:self selector:@selector(animateDarkAst) userInfo:nil repeats:YES];
double randomInterval2 = ((double)arc4random() / 3) * (3 - 1) + 1;
timer3 = [NSTimer scheduledTimerWithTimeInterval:randomInterval2 target:self selector:@selector(animateSmallAst) userInfo:nil repeats:YES];
double randomInterval3 = ((double)arc4random() / 5) * (5 - 1) + 1;
timer4 = [NSTimer scheduledTimerWithTimeInterval:randomInterval3 target:self selector:@selector(animateLightAst) userInfo:nil repeats:YES];
double randomInterval4 = ((double)arc4random() / 6) * (6 - 1) + 1;
timer5 = [NSTimer scheduledTimerWithTimeInterval:randomInterval4 target:self selector:@selector(animateComet) userInfo:nil repeats:YES];
}
return self;
}
-(void) animateDarkAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroiddark setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroiddark];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroiddark.animator.frame = CGRectOffset(_asteroiddark.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateSmallAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidsmall setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidsmall];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidsmall.animator.frame = CGRectOffset(_asteroidsmall.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateLightAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidlight setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidlight];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidlight.animator.frame = CGRectOffset(_asteroidlight.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateComet
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_comet setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_comet];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_comet.animator.frame = CGRectOffset(_comet.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
我该如何处理?我不能一次有 5 个计时器吗?
正确的问题是:"Why does at least one timer work?"
正如您在 documentation 中看到的那样,方法的签名必须采用一个参数(将消息发送给委托的 NSTimer
的实例)。
aSelector The message to send to target when the timer fires.
The selector should have the following signature: timerFireMethod:
(including a colon to indicate that the method takes an argument). The
timer passes itself as the argument, thus the method would adopt the
following pattern:
添加计时器时更改方法和选择器的签名。
我不明白为什么只有 animateDarkAst 动画有效。前两个计时器(一个在 processKeys 上运行的计时器和一个在 animateDarkAst 上运行的计时器)工作正常,但其他计时器则没有。我编写定时器的顺序无关紧要,只有这两种方法适用于各自的定时器。对于其他 3 个动画,屏幕上没有显示任何内容,因为它们的方法(animateLightAst、animateSmallAst、animateComet)中没有处理任何代码。
// Prepare asteroids.
_asteroiddark = [[NSImageView alloc] init];
[_asteroiddark setImage: [NSImage imageNamed:@"asteroiddark"]];
[_asteroiddark setFrame: theModel.darkAstRect];
_asteroidlight = [[NSImageView alloc] init];
[_asteroidlight setImage: [NSImage imageNamed:@"asteroidwhite"]];
[_asteroidlight setFrame: theModel.lightAstRect];
_asteroidsmall = [[NSImageView alloc] init];
[_asteroidsmall setImage: [NSImage imageNamed:@"asteroidsmall"]];
[_asteroidsmall setFrame: theModel.smallAstRect];
// ... and comets
_comet = [[NSImageView alloc] init];
[_comet setImage:[NSImage imageNamed:@"comet"]];
[_comet setFrame: theModel.cometRect];
// Set up key Processing timer for fluid spaceship movement.
timer1 = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(processKeys) userInfo:nil repeats:YES];
// Make a random value for first animation timer.
double randomInterval1 = arc4random() % (4 - 1) + 1;
// Set up key Processing timer for animation.
timer2 = [NSTimer scheduledTimerWithTimeInterval:randomInterval1 target:self selector:@selector(animateDarkAst) userInfo:nil repeats:YES];
double randomInterval2 = ((double)arc4random() / 3) * (3 - 1) + 1;
timer3 = [NSTimer scheduledTimerWithTimeInterval:randomInterval2 target:self selector:@selector(animateSmallAst) userInfo:nil repeats:YES];
double randomInterval3 = ((double)arc4random() / 5) * (5 - 1) + 1;
timer4 = [NSTimer scheduledTimerWithTimeInterval:randomInterval3 target:self selector:@selector(animateLightAst) userInfo:nil repeats:YES];
double randomInterval4 = ((double)arc4random() / 6) * (6 - 1) + 1;
timer5 = [NSTimer scheduledTimerWithTimeInterval:randomInterval4 target:self selector:@selector(animateComet) userInfo:nil repeats:YES];
}
return self;
}
-(void) animateDarkAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroiddark setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroiddark];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroiddark.animator.frame = CGRectOffset(_asteroiddark.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateSmallAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidsmall setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidsmall];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidsmall.animator.frame = CGRectOffset(_asteroidsmall.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateLightAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidlight setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidlight];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidlight.animator.frame = CGRectOffset(_asteroidlight.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateComet
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_comet setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_comet];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_comet.animator.frame = CGRectOffset(_comet.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
我该如何处理?我不能一次有 5 个计时器吗?
正确的问题是:"Why does at least one timer work?"
正如您在 documentation 中看到的那样,方法的签名必须采用一个参数(将消息发送给委托的 NSTimer
的实例)。
aSelector The message to send to target when the timer fires.
The selector should have the following signature: timerFireMethod: (including a colon to indicate that the method takes an argument). The timer passes itself as the argument, thus the method would adopt the following pattern:
添加计时器时更改方法和选择器的签名。