我试图在iphone屏幕上创建一个爆炸,它会快速变大,然后消失。为什么这个计时器没有停止?
NSTimer *explosion = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(explosion) userInfo:nil repeats:YES];
-(void)explosion {
image.image = [UIImage imageNamed:@"explosion.png"];
expsize = expsize + 2.5;
image.frame = CGRectMake(image.frame.origin.x, image.frame.origin.y, expsize, expsize);
if (expsize > 60) {
NSLog(@"%f",expsize);
[explosion invalidate];
explosion = nil;
}
}
答案 0 :(得分:3)
您最有可能使错误的计时器无效。
您创建一个名为explosion的局部变量,该变量与实例变量具有相同的名称。 避免使用相同的名称声明实例变量和局部变量!
答案 1 :(得分:0)
很难确定,因为目前尚不清楚这是否完全是您的代码,但您有两个名为explosion
的变量,其中一个变量分配了NSTimer
;另一个(似乎是一个伊娃)是nil
。
// Variable local to whatever method this is in
NSTimer *explosion = [NSTimer scheduledTimerWithTimeInterval:0.1...
if (expsize > 60) {
NSLog(@"%f",expsize);
// Other variable named "explosion" does not exist.
// This is an ivar? Has not been set.
[explosion invalidate];
假设您已将explosion
声明为属性(并且没有理由不这样做),您应该在创建计时器时使用setter来解决此问题:
[self setExplosion:[NSTimer scheduledTimerWithTimeInterval:...]];
现在,ivar具有计时器实例,您可以使用它来使计时器无效。
另外,请注意您的计时器方法不正确;它must take one parameter是指向计时器的指针。您也可以使用此指针在计时器触发时使其无效。
- (void) fireExplosion: (NSTimer *)tim {
//...
if( expsize > 60 ){
[tim invalidate];
//...
}
}
最后,你有一个最后的命名问题;如果您的属性被称为explosion
,则Cocoa中的约定是访问者应具有相同的名称,但您已使用explosion
作为计时器调用的方法。这可能会导致以后难以跟踪的问题。你应该像我这里一样重命名计时器方法,使用动词来表明发生了什么。
答案 2 :(得分:0)
我建议您使用NSTimer doc要求的选择器形式:- (void)timerFireMethod:(NSTimer*)theTimer
。您可以使“theTimer”无效,并确保您使正确的无效。
当然,如果将“爆炸”声明为属性,那么类中将有两个名为“爆炸”的方法,并且没有关于哪一个被调用的真实线索。
答案 3 :(得分:-1)
如果您在示例中声明了explosion
的发布方式,那么您将隐藏实例变量explosion
。作为建议,您应该使用命名约定来实例变量,例如下划线前缀。现在,如果您只是在触发计时器之后使其无效,则不需要跟踪计时器。你可以在爆炸方法上加一个额外的参数,即定时器explosion:(id)timer
。否则您可以执行以下操作。
@interface X : NSObject
{
NSTimer *_explosion;
}
@end
当您在代码中声明它时,请执行以下操作
...
[_explosion invalidate];
[_explosion release];
//There is a whole 'nother debate on whether or not to retain a scheduled timer
//but I am a stickler for ownership so remember to release this in dealloc
_explosion = [[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(explosion)
userInfo:nil
repeats:YES] retain];
...
-(void)explosion {
image.image = [UIImage imageNamed:@"explosion.png"];
expsize = expsize + 2.5;
image.frame = CGRectMake(image.frame.origin.x, image.frame.origin.y, expsize, expsize);
if (expsize > 60) {
NSLog(@"%f",expsize);
[_explosion invalidate];
[_explosion release];
_explosion = nil;
}
}