Sorry to ask this question, but it's now day 3 I try to solve this problem and have no progress so far.
The problem is this: during a game there is a pause between the user answered a question and the next question. Also in several other cases there are such pauses in gameplay. For this I use one NSTimer.
In .h I have:
@property(nonatomic,retain) NSTimer *scheduleTimer;
and in the .m
@synthesize scheduleTimer;
scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];
now this works just fine. But when the user exits the ViewController I need to invalidate the timer. Otherwise the timer will fire and then crash the app or pops up stuff that does not belong in the other view etc.
Therefore I write:
- (void)viewWillDisappear:(BOOL)animated {
[scheduleTimer invalidate];
}
now this does the job if the timer is actually set. But if there is no such timer scheduled, the app just crashes.
I tried probably everything there is, including @try (which crashes the app too, Zombie says " * -[CFRunLoopTimer invalidate]: message sent to deallocated instance 0x567640"). Since the timer gets released after it is done, a [scheduleTimer isValid] will just crash the app as well.
Now I'm already pretty desperate, and as a last resort I'm thinking of replacing the timer with UIView animateWithDuration that does nothing visible.
However, I think this should be a pretty standard situation. I just don't know why I can't find an answer to this very obvious task. Can you help? Thank you
I think the problem is that the NSTimer
gets autoreleased before you invalidate
it.
So you should do:
scheduleTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO] retain];
And you should also release
the timer in viewWillDisappear:
[scheduleTimer release];
But an even better solution is probably to use the dot property syntax to care of retain/release:
self.scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];
And then:
- (void)viewWillDisappear:(BOOL)animated {
if (self.scheduleTimer != nil) {
[self.scheduleTimer invalidate];
self.scheduleTimer = nil;
}
}
Create a method to invalidate the timer that also sets the property to nil:
- (void) invalidateTimer
{
if (self.scheduleTimer) {
[self.scheduleTimer invalidate];
self.scheduleTimer = nil;
}
}
... and then call that method whenever you invalidate the timer. For example:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear: animated];
[self invalidateTimer];
}
Make sure your timer is retained by using:
self.scheduleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target: self selector: @selector(playFeedbackSound) userInfo: nil repeats: NO];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.