iphone多个NSTimer的麻烦

1 iphone object nstimer

我对编程还是个新手,所以如果这很愚蠢,请原谅。我正在编写一个简单的游戏,需要多个计时器以不同的时间间隔发送不同的消息,因此在创建游戏时,调用以下内容:

[self gameTimerValidate];
[self scoreTimerValidate];

- (void) gameTimerValidate
{
gameTimer = [NSTimer scheduledTimerWithTimeInterval:[myGame gIntervalSpeed] target:self selector:@selector(gameTimerInterval:) userInfo:nil repeats:YES];
}

- (void) scoreTimerValidate
{
scoreTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(scoreTimerInterval:) userInfo:nil repeats:YES];
}
Run Code Online (Sandbox Code Playgroud)

我在头文件(“NSTimer *gameTimer;”)中声明了 scoreTimer 和 gameTimer。我在暂停游戏或完成关卡时使计时器失效,并分别在恢复游戏或进入下一关卡时再次调用上述方法。

我今天花了几个小时试图弄清楚为什么暂停游戏会导致应用程序崩溃。在进行了一些调试后,我注意到 gametimer 的保留计数为 0,而对于 scoretimer 来说,它是 2。当然,我不能使保留计数为 0 的计时器无效,但我不确定这是怎么发生的。

有没有一种特定的方式我必须初始化两个不同的 NStimer?我在这个问题上搜索了几个小时无济于事......

Tec*_*Zen 5

NSTimer 是一个棘手的类。它的行为不像您期望的那样。

首先,定时器实例最终不是由初始化它们的对象保留,而是由 IIRC,NSRunLoop 保留。这意味着如果您有一个创建计时器的对象,即使您销毁了创建它的对象以及自定义代码中的所有其他引用,该计时器仍将继续处于活动状态。计时器将继续发出消息,而您不知道它们来自哪里。

其次,您不能停止/暂停和恢复计时器。当你使它无效时,它就死了。

我建议创建一个轻量级来为您管理计时器,这样您就不必在其余代码中跟踪它。例如

@interface SDL_SimpleTimerController : NSObject {
    NSTimer *currentTimer;
    NSTimeInterval theInterval;
    id theTargetObj;
    SEL theSelector;

    BOOL timerIsRunning;
}
@property (nonatomic,retain) NSTimer *currentTimer;
@property NSTimeInterval theInterval;
@property (nonatomic,retain) id theTargetObj;
@property SEL theSelector;
@property BOOL timerIsRunning;

-(SDL_SimpleTimerController *) initWithInterval:(NSTimeInterval)anInterval forTarget:(id)aTargetObj andSelector:(SEL)aSelector;

-(void) startTimer;
-(void) stopTimer;                                  
@end

@implementation SDL_SimpleTimerController
@synthesize currentTimer;
@synthesize theInterval;
@synthesize theTargetObj;
@synthesize theSelector;
@synthesize timerIsRunning;

-(SDL_SimpleTimerController *) initWithInterval:(NSTimeInterval) anInterval forTarget:(id) aTargetObj andSelector:(SEL) aSelector
{
    self=[super init];
    theInterval=anInterval;
    theTargetObj=aTargetObj;
    theSelector=aSelector;
    timerIsRunning=NO;

    return self;

}// end initWithInterval:   


-(void) startTimer{
    if (currentTimer) { 
        currentTimer=Nil;
    }
    currentTimer=[NSTimer scheduledTimerWithTimeInterval:theInterval  target:theTargetObj selector:theSelector userInfo:Nil repeats:YES];
    timerIsRunning=YES;
}//end startTimer

-(void) stopTimer{
    if (currentTimer) {
        [currentTimer invalidate];
        currentTimer=Nil;
    }
    timerIsRunning=NO;
}// end stopTimer

- (void)dealloc { 
    if (currentTimer) {
        [currentTimer release];
        currentTimer=Nil;
    }
    [theTargetObj release];
    theTargetObj=Nil;
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)