开发者

NSTimer not invalidating or is refiring

so here is the problem i have, i created two NSTimer objects and they are fired when i button is pressed. then the user has 20 seconds to press another button which forces an alert to popup where they enter a validation code, and when they press the confirm button on the alert it is supposed to stop the timer. what is happening is that everything works until they press confirm but instead of the timer stopping it hangs for a second( which im thinking is a delay caused by the keyboard dismiss animation) and then the timer continues. any help would be greatly appreciated and here is all relevant code:

#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];

}


In your confirm method, are you sure that your inputCode.text == codeToConfirm is returning true? Have you tried using [inputCode.text compare:codeToConfirm]? From what I can see, your timers only get invalidated in stopCrack and stopDecrypt, which only get called if that comparison succeeds.


First, you should not be calling "fire" manually unless you want the timer to fire immediately.

Second, you should call -invalidate rather than -release (as you're doing in your -decryptTimerFires and -crackTimerFires methods) when you want your timer to go away, then nil it out as you're doing. You're using the +scheduled... class method, which schedules the timer on the current run loop (which retains it, so it's not up to you to release it). -invalidate removes it from the run loop properly.

From the docs:

This method is the only way to remove a timer from an NSRunLoop object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜