Crash lors de l'utilsation de NSTimer
chbrosso
Membre
Bonjour à tous,
Programmeur C++, je me mets à Cocoa avec une application qui incrémente un compteur toutes les secondes. J'ai donc fait mon nib, avec le textfield et le controlleur qui va bien, et j'ai rajouté un NSTimer dans le contrôleur:
Dans l'implémentation, j'initialise mon timer avec la méthode d'incrémentation de mon contrôleur, et je l'invalide à la désallocation:
Tout se passe bien, le comportement est celui que j'attends. Sauf que quand je ferme la fenêtre, j'ai un crash dans le NSRunLoop:
J'ai l'impression que le timer est déclenché à un moment où la cible (mon contrôleur) n'existe plus, mais je ne comprends pas... Qu'est-ce qui ne va pas?
Merci pour votre aide,
Charles
Programmeur C++, je me mets à Cocoa avec une application qui incrémente un compteur toutes les secondes. J'ai donc fait mon nib, avec le textfield et le controlleur qui va bien, et j'ai rajouté un NSTimer dans le contrôleur:
<br />@interface UpController : NSObject<br />{<br /> IBOutlet Upper *up;<br /> IBOutlet NSTextField *valueField;<br /><br /> NSTimer* timer;<br />}<br />- (IBAction)up:(id)sender;<br />- (void)awakeFromNib;<br />- (void) dealloc ;<br />@end<br />
Dans l'implémentation, j'initialise mon timer avec la méthode d'incrémentation de mon contrôleur, et je l'invalide à la désallocation:
@implementation UpController<br /><br />- (IBAction)up:(id)sender<br />{<br /> [valueField setIntValue:[up upIt]];<br />}<br /><br />- (void)awakeFromNib<br />{<br /> [valueField setIntValue:0];<br /> timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(up:) userInfo:nil repeats:TRUE];<br />}<br /><br />- (void) dealloc <br />{<br /> [timer invalidate];<br /> [super dealloc];<br />}<br />
Tout se passe bien, le comportement est celui que j'attends. Sauf que quand je ferme la fenêtre, j'ai un crash dans le NSRunLoop:
<br />#0 0x90a594d1 in objc_msgSend<br />#1 0x00337d60 in ??<br />#2 0x9283b2de in __NSFireTimer<br />#3 0x9082d7e2 in CFRunLoopRunSpecific<br />#4 0x9082cace in CFRunLoopRunInMode
J'ai l'impression que le timer est déclenché à un moment où la cible (mon contrôleur) n'existe plus, mais je ne comprends pas... Qu'est-ce qui ne va pas?
Merci pour votre aide,
Charles
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ton contrôleur, lui, n'est pas désalloué, donc le timer continue à fonctionner (car il n'appartient pas à la fenêtre).
Or, la méthode du timer va tenter de modifier la valeur du textField détruit...
Résultat ? Crash !
.
Ce delegate sera appelé à la fermeture de la fenêtre : c'est donc dans cette méthode que tu dois invalider le timer.
Le contrôleur n'a pas besoin d'être désalloué.
.
Merci beaucoup, maintenant ça marche!