NSTimer无效无效

时间:2011-10-03 20:44:35

标签: iphone objective-c nstimer

我试图在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;
    }
}

4 个答案:

答案 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;
    }
}