2009-07-14 4 views
6

Se ho una vista con un performSelector set a fuoco dopo un ritardo:Come uccidere un selettore che è impostato per sparare dopo un ritardo (su iPhone)?

[self performSelector:@selector(generateBall) withObject:NULL afterDelay:1.5]; 

... ma io removeFromSuperview quella vista prima che i fuochi di selezione (per esempio, a causa di interazione con l'utente), allora il mio crash app .

C'è un modo per uccidere il selettore ritardato nel metodo dealloc per quella vista?

EDIT:

Ho provato sia:

[[NSRunLoop mainRunLoop] cancelPerformSelector:theBall target:self argument:nil]; 

e

[[NSRunLoop currentRunLoop] cancelPerformSelector:theBall target:self argument:nil]; 

e mentre sia il lavoro (che mi permette di caricare una nuova vista), caricare la vista precedente estremità a darmi uno schermo grigio.

Non sono stato in grado di trovare alcun tutorial o altre informazioni su cancelPerformSelector diversi da quelli dei documenti Apple che sono stati elencati e la documentazione sui thread e sui loop di esecuzione sembra essere molto contorta (soprattutto perché non elencano lavoro esempi di codice, che mi renderebbero più facile il passaggio e la comprensione di ciò che stava accadendo).

risposta

15

perché sto utilizzando performSelector: afterDelay, l'unico modo che ho potuto correttamente "uccidere" qualsiasi funzionalità precedentemente richiesto ma non lanciato sta usando :

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:theBall object:nil]; 

L'esempio di codice seguente mostra come funziona (creare un nuovo XCode proj View template ect chiamato "selezionare", e sostituire il file selectViewController.h con questo):

#import "selectViewController.h" 

@implementation selectViewController 

UILabel *lblNum; 
UIButton *btnStart, *btnStop; 
int x; 

- (void) incNum { 
    x++; 
    lblNum.text = [NSString stringWithFormat:@"%i", x]; 
    [self performSelector:@selector(incNum) withObject:NULL afterDelay:1.0]; 
} 

- (void) stopCounter { 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(incNum) object:NULL]; 
} 

- (void)viewDidLoad { 
    x = 0; 

    lblNum = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)]; 
    lblNum.textAlignment = UITextAlignmentCenter; 
    [self.view addSubview:lblNum]; 

    btnStart = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    btnStart.frame = CGRectMake(40, 270, 240, 30); 
    [btnStart setTitle:@"start" forState:UIControlStateNormal]; 
    [btnStart addTarget:self action:@selector(incNum) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:btnStart]; 

    btnStop = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    btnStop.frame = CGRectMake(40, 310, 240, 30); 
    [btnStop setTitle:@"stop" forState:UIControlStateNormal]; 
    [btnStop addTarget:self action:@selector(stopCounter) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:btnStop]; 

    [self performSelector:@selector(incNum) withObject:NULL afterDelay:1.0]; 
    [super viewDidLoad]; 
} 


- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
} 

- (void)viewDidUnload { 
} 

- (void)dealloc { 
    [lblNum release]; 
    [super dealloc]; 
} 

@end 
3

ho trovato che questo funziona alla grande:

[NSObject cancelPreviousPerformRequestsWithTarget:self];