xcode NSTimer 崩溃,当我调用 [Timer isValid] 或 [Timer invalidate]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3692359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSTimer crashes, when I call [Timer isValid] or [Timer invalidate]
提问by esanits
I have two NSTimers in my iPhone app. DecreaseTimer works fine, but TimerCountSeconds crashes when I call [timerCountSeconds isValid] or [timerCountSeconds invalidate]. They are used like this:
我的 iPhone 应用程序中有两个 NSTimer。DecreaseTimer 工作正常,但当我调用 [timerCountSeconds isValid] 或 [timerCountSeconds invalidate] 时 TimerCountSeconds 崩溃。它们是这样使用的:
-(id)initialize { //Gets called, when the app launches and when a UIButton is pressed
if ([timerCountSeconds isValid]) {
[timerCountSeconds invalidate];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //Gets called, when you begin touching the screen
//....
if ([decreaseTimer isValid]) {
[decreaseTimer invalidate];
}
timerCountSeconds = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
//....
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {//Gets called, when you stop touching the screen(not if you press the UIButton for -(id)initialize)
//...
decreaseTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(decrease) userInfo:nil repeats:YES];
//...
}
-(void)comept3 { //Gets calles when you rubbed the screen a bit
if ([timerCountSeconds isValid]) {
[timerCountSeconds invalidate];
}
}
What did I do wrong? Can you please help me?
我做错了什么?你能帮我么?
回答by Shaggy Frog
You should set an NSTimer
object to nil
after you invalidate
it, since the invalidate
method call also does a release
(as per the Apple docs). If you don't, calling a method on it like isValid
could cause your crash.
你应该在你之后设置一个NSTimer
对象,因为方法调用也做了(根据 Apple 文档)。如果你不这样做,调用它的方法可能会导致你的崩溃。nil
invalidate
invalidate
release
isValid
回答by jayesh kavathiya
[objTimer retain];
Then it will not crash any time. Use this after initializing the timer so it will work fine....
然后它不会在任何时候崩溃。在初始化计时器后使用它,这样它就可以正常工作....
回答by Chuck
Most likely the timer stored in that variable has already been deallocated. You need to retain it if you want to keep it around for an arbitrarily long time.
很可能存储在该变量中的计时器已经被释放。如果您想将其保留任意长时间,则需要保留它。
回答by zzzz
You need to set the timer in main thread. NSTimer will not be fired in background thread.
您需要在主线程中设置计时器。NSTimer 不会在后台线程中被触发。
Objc:
dispatch_async(dispatch_get_main_queue(), ^{ _timer = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(YOUR_METHOD) userInfo:nil repeats:YES]; });
Swift:
dispatch_async(dispatch_get_main_queue()) { timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: "YOUR_METHOD", userInfo: nil, repeats: true) }
对象:
dispatch_async(dispatch_get_main_queue(), ^{ _timer = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(YOUR_METHOD) userInfo:nil repeats:YES]; });
迅速:
dispatch_async(dispatch_get_main_queue()) { timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: "YOUR_METHOD", userInfo: nil, repeats: true) }
回答by olliej
You need to actually initialise the TimerCountSeconds
and DecreaseTimer
members in initialise. Assuming you're control flow is:
您需要在初始化中实际初始化TimerCountSeconds
和DecreaseTimer
成员。假设你的控制流是:
...
myObject = [[MyObject alloc] initialize];
...
[myObject touchesBegan:...]
...
[myObject touchesEnded:...]
...
Then when you call initialize
TimerCountSeconds
has not been initialised, so you're logically doing
然后当你调用initialize
TimerCountSeconds
还没有被初始化,所以你在逻辑上做
[<random pointer> isValid]
Which will crash. Similarly DecreaseTimer is invalid the first time you call touchesBegan.
哪个会崩溃。同样,第一次调用 touchesBegan 时,DecreaseTimer 无效。
In your initialise method you will need to actually initialise everything, before you attempt to use anything.
在您的初始化方法中,您需要在尝试使用任何东西之前实际初始化所有内容。
You also appear to be leaking timers (touchesBegin
invalidates the timer but does not release it)
您似乎也在泄漏计时器(touchesBegin
使计时器无效但不释放它)