问题无效&重新创建 NSTimer
我在启动和运行时遇到问题停止 NSTimer。文档说计时器被 [timer invalidate] 停止;
我有一个这样声明的计时器对象
.h
NSTimer *incrementTimer;
@property (nonatomic, retain) NSTimer *incrementTimer;
.m
@synthesize incrementTimer;
-(void)dealloc {
[incrementTimer release];
[super dealloc];
}
- 通常。
当需要时,我的方法会执行以下操作:
-(void)setGenCount {
if(!condition1 && condition2) {
incrementTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(incrementBatteryVoltage:)
userInfo: nil
repeats: YES];
}
}
上面的一切都工作正常。但是,一旦该计时器完成其工作,我希望它自行失效。我使计时器无效,因为有一个相同的减量方法可以被调用,并且如果它仍然处于活动状态,则会与增量计时器对抗。 (以前,我注意到我的两个计时器,如果处于活动状态,会通过增加和减少值(一种战斗)来作用于同一个 ivar...而不会崩溃)调用的选择器的工作原理如下:
-(void)incrementBatteryVoltage:(NSTimer *)timer {
if(battVoltage < 24.0) {
generatorDisplay.battVoltage += 0.1;
}
if(battery1Voltage == 24.0) {
[timer invalidate];
}
}
我有一个 equal 方法这会减少电池数量。 (前面提到过)
由于我的程序设计:界面模拟电压显示。当“机器”关闭时,我希望所有计时器都无效,无论电压值是多少。我通过检查计时器是否有效来做到这一点。
-(void)deEnergizeDisplays {
if([decrementTimer isValid]) {
[decrementTimer invalidate];
decrementTimer = nil;
}
if([incrementTimer isValid]) {
[incrementTimer invalidate];
incrementTimer = nil;
}
我遇到了许多“BAD_ACCESS”崩溃。错误的线路调用始终指向我的 [timer isValid] 调用。看来如果定时器失效的话...指针 也不存在。我知道 [timer invalidate] 消息会禁用计时器,然后将其从运行循环中删除,然后将其释放。我的理解是:根据其命名约定,它是一个自动释放的对象。
我的想法是:如果我发送保留消息,引用不应该仍然存在吗?我尝试了几种组合,去掉:
timer = nil;
甚至代替:
if([timer isValid])
我尝试过:
if([timer != nil])
和:
if(timer)
我总是遇到同样的崩溃。感谢您对启动和使用的任何帮助停止 NSTimers。
I'm having problems starting & stopping NSTimers. The docs say that a timer is stopped by [timer invalidate];
I have a timer object declared as such
.h
NSTimer *incrementTimer;
@property (nonatomic, retain) NSTimer *incrementTimer;
.m
@synthesize incrementTimer;
-(void)dealloc {
[incrementTimer release];
[super dealloc];
}
-The usual.
When it's needed, my method does the following:
-(void)setGenCount {
if(!condition1 && condition2) {
incrementTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(incrementBatteryVoltage:)
userInfo: nil
repeats: YES];
}
}
Everything above works fine. However, once that timer does it's job, I want it to invalidate itself. I invalidate the timer because there is an equal decrement method that could be called and would fight against the incrementTimer if it was still active. (Previously, I noticed that my two timers, if active, were acting on the same ivar by increasing & decreasing the value (a sort of fight)... without crashing) The selector called works as follows:
-(void)incrementBatteryVoltage:(NSTimer *)timer {
if(battVoltage < 24.0) {
generatorDisplay.battVoltage += 0.1;
}
if(battery1Voltage == 24.0) {
[timer invalidate];
}
}
I have an equal method that Decrements the battery count. (previously mentioned)
Due to my program design: the interface simulates a voltage display. When the "machine" is turned off, I want all the timers invalidated, regardless of what any voltage value is. I'm doing this by checking to see if the timer is valid.
-(void)deEnergizeDisplays {
if([decrementTimer isValid]) {
[decrementTimer invalidate];
decrementTimer = nil;
}
if([incrementTimer isValid]) {
[incrementTimer invalidate];
incrementTimer = nil;
}
I'm getting numerous "BAD_ACCESS" crashes. The erroneous line call is always pointing toward my [timer isValid] call. It seems that if the timer is invalidated... the pointer
doesn't exist either. I know that the [timer invalidate] message disables the timer and then it is removed from the run loop and then it is released. And my understanding is: it is an autoreleased object per it's naming covention.
My thought are: If I'm sending a retain message, shouldn't the reference still exist? I've tried several combinations, taking away:
timer = nil;
or even instead of:
if([timer isValid])
I tried :
if([timer != nil])
and:
if(timer)
I always get the same crash. Thanks for any help on starting & stopping NSTimers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新:请参阅达伦的回答。问题是您在设置计时器时没有使用属性访问器。而不是:
您应该:
self.propertyName = ...
语法将调用您的访问器方法,从而自动保留您发送给它的对象(因为您的属性设置为保留
)。简单地调用propertyName = ...
不会使用属性访问器。您只需直接更改 ivar 的值即可。更新 #2: 在与 Peter Hosey 进行了一次富有启发性的对话(参见评论)后,我删除了之前的建议,即“永远不要保留或释放”计时器对象。我还完全重写了我之前的代码,因为我认为以下是更好的方法:
现在,您只需设置目标电池电压,计时器的魔法就会在幕后发生:
您的关机方法如下所示:
UPDATE: See Darren's answer. The problem is that you are not using your property accessor when setting the timers. Instead of:
You should have:
The
self.propertyName = ...
syntax will call your accessor method, and thereby automatically retain the object that you send to it (since your property is set up asretain
). Simply callingpropertyName = ...
does not use the property accessor. You are simply changing the value of your ivar directly.UPDATE #2: After an enlightening conversation with Peter Hosey (see comments), I have removed my earlier suggestion to "never retain or release" your timer object. I have also completely re-written my earlier code because I think the following is a better approach:
Now, you can simply set a target battery voltage, and the timer magic will happen behind the scenes:
Your power-off method would look as follows:
您需要在
setGenCount
中保留
分配给incrementTimer
的值。您可以使用合成属性自动执行此操作,该属性可通过self.
访问:You need to
retain
the value assigned toincrementTimer
insetGenCount
. You can do this automatically by using your synthesized property, which is accessed viaself.
: