2010-09-12 4 views
2

J'essaye d'exécuter une méthode de mon délégué d'application, qui enregistre un objet dans l'autre classe aussi bien qu'invalide un temporisateur. Je l'ai mis en place de sorte que lorsque mon application se termine, il exécute la méthode dans ma classe et enregistre et arrête le chronomètre.iPhone: invalider NSTimer de l'application bloque l'application de délégué

Dans délégué app:

- (void)applicationWillResignActive:(UIApplication *)application { 

    // Save the mission because they are leaving the app 
    if ([timeRun hasScore]) { 
     [timeRun resetWithSave]; 
    } 

} 

La méthode qu'il appelle dans la classe "timeRun":

- (void)resetWithSave { 
    // Save 
    self.counterInt = 150; 
    self.timer.text = [self timeInSeconds:counterInt]; 
    [start setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 
    self.started = NO; 
    self.score.text = @"0"; 
    [self saveMission]; 
    if ([countTimer isValid]) { 
     [countTimer invalidate]; 
    } 
    [table scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; 
} 

Mais, je recevais des accidents:

2010-09-11 19:35:21.503 Score Card[2747:307] -[__NSCFType isValid]: unrecognized selector sent to instance 0x19e190 
2010-09-11 19:35:21.594 Score Card[2747:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType isValid]: unrecognized selector sent to instance 0x19e190' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x30897ed3 __exceptionPreprocess + 114 
    1 libobjc.A.dylib      0x3002f811 objc_exception_throw + 24 
    2 CoreFoundation      0x30899683 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102 
    3 CoreFoundation      0x308411d9 ___forwarding___ + 508 
    4 CoreFoundation      0x30840f90 _CF_forwarding_prep_0 + 48 
    5 Score Card       0x00006b3d -[TimeRun resetWithSave] + 272 
    6 Score Card       0x00002b39 -[Score_CardAppDelegate applicationWillResignActive:] + 80 
    7 UIKit        0x31ea6879 -[UIApplication _setActivated:] + 212 
    8 UIKit        0x31eda4ab -[UIApplication _handleApplicationSuspend:eventInfo:] + 238 
    9 UIKit        0x31eab301 -[UIApplication handleEvent:withNewEvent:] + 2200 
    10 UIKit        0x31eaa901 -[UIApplication sendEvent:] + 44 
    11 UIKit        0x31eaa337 _UIApplicationHandleEvent + 5110 
    12 GraphicsServices     0x31e4504b PurpleEventCallback + 666 
    13 CoreFoundation      0x3082cce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26 
    14 CoreFoundation      0x3082cca7 __CFRunLoopDoSource1 + 166 
    15 CoreFoundation      0x3081f56d __CFRunLoopRun + 520 
    16 CoreFoundation      0x3081f277 CFRunLoopRunSpecific + 230 
    17 CoreFoundation      0x3081f17f CFRunLoopRunInMode + 58 
    18 GraphicsServices     0x31e445f3 GSEventRunModal + 114 
    19 GraphicsServices     0x31e4469f GSEventRun + 62 
    20 UIKit        0x31e51123 -[UIApplication _run] + 402 
    21 UIKit        0x31e4f12f UIApplicationMain + 670 
    22 Score Card       0x000029ef main + 70 
    23 Score Card       0x000029a4 start + 40 
) 
terminate called after throwing an instance of 'NSException' 
Program received signal: “SIGABRT”. 
kill 
quit 

Pourquoi cette planter mon application?

+0

Montrez-nous la définition de 'countTimer' – jer

Répondre

0

Il semble que le minuteur n'ait jamais été initialisé ou qu'il ait été relâché. Parfois, des exceptions comme celle-là seront lancées avec un objet aléatoire quand il est aussi nul. Vérifiez vos pointeurs et gardez le compte!

5

Sur une intuition, vous faites quelque chose comme

countTimer = [NSTimer scheduledTimerWithTarget:...]; 

... 

if ([countTimer isValid]) 
{ 
    [countTimer invalidate]; 
} 

... 


if ([countTimer isValid]) 
{ 
    [countTimer invalidate]; 
} 

A « programmée » timer est ajoutée à la boucle d'exécution pour vous. Il est ensuite conservé par la boucle d'exécution. Invalidant il le supprime de la boucle d'exécution, il est donc libéré. Si rien d'autre ne le retient, il est désaffecté. Lorsque vous essayez de l'utiliser à nouveau, il se bloque.

Essayez quelque chose comme [countTimer invalidate]; countTimer = nil;

Alternativement, vous pouvez conserver la minuterie, mais notez que la minuterie conserve son objectif il est donc facile de se retrouver avec un cycle retenir.

+0

Yah. Puisque vous n'avez pas conservé le minuteur (comme vous ne devriez généralement pas le faire), vous ne savez pas quand il sera publié, sauf qu'il le sera après l'appel de la méthode de rappel. Vous devez définir sa référence à zéro à ce moment-là, ou chaque fois que vous l'annulez, car il sera automatiquement libéré après cela. –

+1

Vous savez quand il est publié * par la boucle d'exécution *. Vous ne savez pas quand il sera libéré; c'est différent. –