NSTimer没有失效或正在重新开始

时间:2010-09-29 19:20:26

标签: iphone objective-c cocoa-touch

所以这就是我遇到的问题,我创建了两个NSTimer对象,按下i按钮时会触发它们。那么用户有20秒的时间按下另一个按钮,该按钮强制在他们输入验证码时弹出警报,当他们按下警报上的确认按钮时,它应该停止计时器。发生的事情就是一切正常,直到他们按下确认但不是计时器停止它会挂起一秒钟(我认为这是由键盘解除动画引起的延迟),然后计时器继续。任何帮助将不胜感激,这里是所有相关的代码:

#import "hackergameViewController.h"
#import <AudioToolbox/AudioToolbox.h>


@implementation hackergameViewController

@synthesize decryptLabel, crackLabel, decryptButton, crackButton, submit, numberToDecrypt, numberToCrack, stopDecryptButton, stopCrackButton, inputCode;
@synthesize soundFileURLRefBeep;
@synthesize soundFileURLRefBuzz;
@synthesize soundFileObjectBeep;
@synthesize soundFileObjectBuzz;


NSTimer *decryptTimer;
NSTimer *crackTimer;
int crackTime;
int decryptTime;
NSString *codeToConfirm;

#pragma mark UIAlertView
- (void)confirm:(UIAlertView *)confirm clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex == 0){
        [confirm dismissWithClickedButtonIndex:0 animated:YES];
    }
    else {
            if (inputCode.text == codeToConfirm) {
            [self stopCrack];
            [self stopDecrypt];
        }
    }
}

-(void) generateDecryptionCode{
    codeToConfirm = [NSString stringWithFormat:@"%i%i%i%i%i%i", arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10];
    numberToDecrypt.text = codeToConfirm;
}

-(void) generateCrackCode{
    codeToConfirm = [NSString stringWithFormat:@"%i%i%i%i%i%i%i%i%i%i", arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10,arc4random() % 10];
    numberToCrack.text = codeToConfirm;
}

- (void)dealloc {
    [decryptLabel release];
    [decryptButton release];
    [crackLabel release];
    [crackButton release];
    [submit release];
    [numberToCrack release];
    [numberToDecrypt release];
    [super dealloc];
}

- (void) confirmCode{
    UIAlertView *confirm = [[UIAlertView alloc] initWithTitle:@"Confirm Code" message:@"Please Input The Correct Code:"  delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Confirm Code", nil];
    inputCode = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
    CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
    [confirm setTransform:myTransform];
    [inputCode setBackgroundColor:[UIColor whiteColor]];
    [confirm addSubview:inputCode];
    [confirm show];
    [confirm release];
    [inputCode release];

}


- (void) decryptTimerFires{

    if(decryptTime > 0){
        decryptTime--;
        decryptLabel.text = [NSString stringWithFormat:@"%g",    (float)decryptTime/10];
        if(decryptTime%10 == 0){
            AudioServicesPlaySystemSound (self.soundFileObjectBeep);
        }

    }
    else{
        [decryptTimer release];
        decryptTimer = nil;
    }
}
- (void) crackTimerFires{

    if(crackTime > 0){

        crackTime--;
        crackLabel.text = [NSString stringWithFormat:@"%g", (float)crackTime/10];
        if(crackTime%10 == 0){
            AudioServicesPlaySystemSound (self.soundFileObjectBeep);
        }
        else if(crackTime == 0){
            AudioServicesPlaySystemSound (self.soundFileObjectBuzz);
        }
    }
    else{
        [crackTimer release];
        crackTimer = nil;
    }
}

-(void) stopDecrypt{
    [decryptTimer invalidate];
    [decryptTimer release];
    decryptTimer = nil;
}
-(void) stopCrack{
    [crackTimer invalidate];
    [crackTimer release];
    crackTimer = nil;
}

-(IBAction)decrypt{
    [self generateDecryptionCode];
    decryptTime = 200;
    decryptTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(decryptTimerFires) userInfo:nil repeats:YES];
    [decryptTimer fire];

}

-(IBAction)crack{
    [self generateCrackCode];
    crackTime = 200;
    crackTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(crackTimerFires) userInfo:nil repeats:YES];
    [crackTimer fire];

}

2 个答案:

答案 0 :(得分:0)

首先,您不应手动调用“fire”,除非您希望立即触发计时器。

其次,当你希望计时器消失时,你应该调用-invalidate而不是-release(正如你在-decryptTimerFires和-crackTimerFires方法中所做的那样),然后将其作为你在做。你正在使用+ scheduled ...类方法,该方法在当前的运行循环中调度计时器(保留它,因此不能由你来释放它)。 -invalidate将其从运行循环中正确删除。

来自文档:

  

此方法是唯一可以删除的方法   来自NSRunLoop对象的计时器。

答案 1 :(得分:0)

在您的确认方法中,您确定inputCode.text == codeToConfirm正在返回true吗?您是否尝试过使用[inputCode.text compare:codeToConfirm]?从我所看到的情况来看,您的计时器只会在stopCrackstopDecrypt中失效,只有在比较成功时才会被调用。