2009-07-14 3 views
6

Si j'ai vue avec un performSelector mis à feu après un délai:Comment tuer un sélecteur qui se déclenche après un délai (sur l'iPhone)?

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

... mais je removeFromSuperview ce point de vue avant que les feux de sélection (par exemple, en raison de l'interaction de l'utilisateur), puis plantage de mon application .

Existe-t-il un moyen de tuer le sélecteur retardé dans la méthode dealloc pour cette vue?

EDIT:

J'ai essayé à la fois:

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

et

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

et alors que les deux travaux (me permettant de charger une nouvelle vue), le chargement des extrémités de vue précédente en me donnant un écran gris.

Je n'ai pas trouvé de didacticiels ou d'autres informations sur cancelPerformSelector autres que les documents Apple répertoriés, et la documentation sur les threads et les boucles d'exécution semble très compliquée (principalement parce qu'ils ne lisent pas échantillons de code, ce qui me faciliterait la tâche pour comprendre et comprendre ce qui se passait).

Répondre

15

Parce que j'utilise performSelector afterDelay, la seule façon que je suis en mesure de bien « tuer » toutes les fonctionnalités précédemment demandées mais non lancé utilise :

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

L'exemple de code suivant montre comment cela fonctionne (créer un nouveau modèle View XCode proj ect appelé « sélectionner » et remplacer le fichier selectViewController.h à ce sujet):

#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

J'ai trouvé que cela fonctionne très bien:

[NSObject cancelPreviousPerformRequestsWithTarget:self]; 
Questions connexes