How to properly invalidate an NSTimer
I've got an iPhone app with an NSTimer called pressTimer that goes off every time someone touches this button. The problem is they touch the button a lot, and I want the timer to stop when they lift up their finger. So I declared pressTimer in my .h and synthes开发者_运维百科ized it in .m then assigned and started it on the TouchDown action I created. I use the code [pressTimer invalidate] on my TouchUpInside action that should cancel the timer, since it's a global variable. It seems to cancel the timer fine, but then when I go to actually trip the timer, the program freezes up completely, even though I get no code errors or warnings. I'm a noob, so please don't be too rough :0
Update: Console logs- Thanks guys!
continue
2010-07-01 16:39:30.981 Clickkr[1573:307] -[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40
2010-07-01 16:39:30.999 Clickkr[1573:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40'
*** Call stack at first throw:
(
0 CoreFoundation 0x309a5fd3 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x318b58a5 objc_exception_throw + 24
2 CoreFoundation 0x309a9a77 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x309a8f15 ___forwarding___ + 508
4 CoreFoundation 0x3093b680 _CF_forwarding_prep_0 + 48
5 Clickkr 0x00002b23 -[MyViewController addOne:] + 42
6 CoreFoundation 0x309307ad -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
7 UIKit 0x31e1f829 -[UIApplication sendAction:to:from:forEvent:] + 84
8 UIKit 0x31e1f7c9 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
9 UIKit 0x31e1f79b -[UIControl sendAction:to:forEvent:] + 38
10 UIKit 0x31e1f4ed -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
11 UIKit 0x31e1fb3b -[UIControl touchesEnded:withEvent:] + 342
12 UIKit 0x31e1e4ed -[UIWindow _sendTouchesForEvent:] + 368
13 UIKit 0x31e1de67 -[UIWindow sendEvent:] + 262
14 UIKit 0x31e19b5b -[UIApplication sendEvent:] + 298
15 UIKit 0x31e19507 _UIApplicationHandleEvent + 5022
16 GraphicsServices 0x30a8c147 PurpleEventCallback + 666
17 CoreFoundation 0x3097baab __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
18 CoreFoundation 0x3097d84f __CFRunLoopDoSource1 + 166
19 CoreFoundation 0x3097e62d __CFRunLoopRun + 520
20 CoreFoundation 0x309278eb CFRunLoopRunSpecific + 230
21 CoreFoundation 0x309277f3 CFRunLoopRunInMode + 58
22 GraphicsServices 0x30a8b6ef GSEventRunModal + 114
23 GraphicsServices 0x30a8b79b GSEventRun + 62
24 UIKit 0x31dc32a7 -[UIApplication _run] + 402
25 UIKit 0x31dc1e17 UIApplicationMain + 670
26 Clickkr 0x00002333 main + 70
27 Clickkr 0x000022e8 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
This is the way I invalidate timers:
[timer invalidate];
timer = nil;
The problem you're probably having is that once your timer is invalidated, it is removed from the runtime loop and when someone wants to access it, your program crashes. After invalidating it, just make it so that it is nil. That way if someone wants to send a message or do anything to it, it'll send it to nil.
@interface
NSTimer * yourTimer;
@property (nonatomic, retain) yourTimer;
@synthesize yourTimer;
@implement
self.yourTimer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(yourSelector)
userInfo:nil
repeats:NO];
//Wherever you want to stop the timer,
[yourTimer invalidate];
self.yourTimer = nil;
The log tells something wrong with addOne
... how's it related to the timer?
Guys I figured it out after a little bit of messing with it. Anauel's method for stopping timers worked great, but for some reason my method name was clashing with the timer's selector, so I changed them both. I also added Anauel's code to the method I used as a selector. Thanks!
I would better add a check of the validity flag and timer object instance
-(void) clearKeepAliveTimer {
if(keepAliveTimer && [keepAliveTimer isValid]) {
[keepAliveTimer invalidate];
keepAliveTimer = nil;
} }
精彩评论