我尝试使用 nstimer 通过点击来显示/隐藏 View 。
@interface
@property (nonatomic, retain)NSTimer *timer;
UIView *view;
@implementation
view.hiden=YES;
- (void)handleTap:(UITapGestureRecognizer *)sender{
if([timer isValid)]{
timer.invalidate;///that gives me _EXC_BAD_ACCESS
}
view.hiden=NO;
timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(targetMethod)
userInfo:nil
repeats:NO];
}
-(void)targetMethod{
view.hiden=YES;
}
如果您对这段代码有所了解,就可以看出问题所在。如果我点击一次并等待 3 秒,一切都很好。但如果我点击它并在 1.5 秒后再次点击,它应该制作另一个计时器盒并在 3 秒后隐藏它,但它在 1.5 秒后隐藏它,因为旧的正在开火。
如您所见,我试图使其无效,但出现错误。
那么我怎样才能以正确的方式销毁它呢?
最佳答案
像这样:
- (void)timerFired:(id)sender {
_timer = nil;
// do thing here
}
- (IBAction)handleTap:(id)sender {
[_timer invalidate];
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:NO];
}
- (void)dealloc {
[_timer invalidate];
}
这里有几件关键的事情你需要做:
- 在处理计时器触发的代码中,将实例变量设置为 nil。
- 在创建新计时器之前使旧计时器无效。
- 在使计时器失效之前,不要担心检查计时器的有效性。如果您遵循此技术,计时器将有效或为零。在 nil 上调用
invalidate
是绝对安全的。 - 您不必在使它无效和重新分配它之间将
_timer
设为 nil;这段代码都在主线程上。但是,如果你只是取消计时器,你会的。- 这样做的原因是这个定时器已经被安排在runloop上。这保证它不会触发,直到运行循环的下一次迭代。在您返回之前,runloop 不会迭代。
- 在
dealloc
中,您应该使计时器无效。 (您在viewDidDisppear:
中执行此操作可能更合适;如果您这样做,请确保之后将其置零。)
关于ios - 如果新的被解雇,如何取消以前的 NSTimer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22236007/