Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong><em>UPDATE:</em></strong> See <a href="https://stackoverflow.com/questions/2188064/problems-invalidating-re-creating-nstimers/2188092#2188092">Darren's answer</a>. The problem is that you are not using your property accessor when setting the timers. Instead of:</p> <pre><code>incrementTimer = [NSTimer ... </code></pre> <p>You should have:</p> <pre><code>self.incrementTimer = [NSTimer ... </code></pre> <p>The <code>self.propertyName = ...</code> syntax will call your accessor method, and thereby automatically retain the object that you send to it (since your property is set up as <code>retain</code>). Simply calling <code>propertyName = ...</code> does <em>not</em> use the property accessor. You are simply changing the value of your ivar directly.</p> <hr> <p><strong><em>UPDATE #2:</em></strong> 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:</p> <blockquote> <p><strong>Controller.h</strong>:</p> </blockquote> <pre><code>NSTimer *voltageTimer; float targetBatteryVoltage; ... @property (nonatomic, retain) NSTimer *voltageTimer; </code></pre> <blockquote> <p><strong>Controller.m</strong>:</p> </blockquote> <pre><code>@implementation Controller @synthesize voltageTimer; - (void)stopVoltageTimer { [voltageTimer invalidate]; self.voltageTimer = nil; } - (void)setTargetBatteryVoltage:(float)target { [voltageTimer invalidate]; targetBatteryVoltage = target; self.voltageTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector: @selector(updateBatteryVoltage:) userInfo: nil repeats: YES]; } - (void)updateBatteryVoltage:(NSTimer *)timer { const float increment = 0.1; if (abs(battVoltage - targetBatteryVoltage) &lt; increment) { [timer invalidate]; } else if (battVoltage &lt; targetBatteryVoltage) { generatorDisplay.battVoltage += increment; } else if (battVoltage &gt; targetBatteryVoltage) { generatorDisplay.battVoltage -= increment; } } </code></pre> <p>Now, you can simply set a target battery voltage, and the timer magic will happen behind the scenes:</p> <pre><code>[self setTargetBatteryVoltage:24.0]; </code></pre> <p>Your power-off method would look as follows:</p> <pre><code>- (void)deEnergizeDisplays { [self stopVoltageTimer]; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload