Iphone NSTimer未失效或正在刷新

Iphone NSTimer未失效或正在刷新,iphone,objective-c,cocoa-touch,Iphone,Objective C,Cocoa Touch,这里是我遇到的问题,我创建了两个NSTimer对象,当我按下按钮时,它们被触发。然后,用户有20秒的时间按下另一个按钮,强制弹出警报,在其中输入验证代码,当用户按下警报上的确认按钮时,应停止计时器。发生的事情是,在他们按下确认键之前,一切都正常,但不是计时器停止,而是它挂起了一秒钟,我想这是键盘关闭动画导致的延迟,然后计时器继续。非常感谢您的帮助,以下是所有相关代码: #import "hackergameViewController.h" #import <AudioToolbox/Au

这里是我遇到的问题,我创建了两个NSTimer对象,当我按下按钮时,它们被触发。然后,用户有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];

}

首先,您不应该手动调用fire,除非您希望计时器立即启动

第二,当您希望计时器消失时,应该像在-decryptTimerFires和-crackTimerFires方法中那样调用-invalidate而不是-release,然后在执行时将其置零。您正在使用+计划的。。。类方法,该方法在保留计时器的当前运行循环上调度计时器,因此不由您来释放它-invalidate会正确地将其从运行循环中移除

从文档中:

此方法是删除的唯一方法 来自nsrunlop对象的计时器


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

我尝试了您的建议,但仍然有效,我刚刚意识到这一定与比较有关,因为我已将StopDecrack和StopDecrack连接到按钮,并且按钮工作正常。inputCode.text是否返回一个可以与NSString进行比较的值,或者我必须键入cast或其他内容?@Joe inputCode.text返回一个NSString,因此这些值应该是可比较的。由于其中一个字符串是由用户输入的,localizedCompare:可能会更好地为您服务。