title: Correct handling / cleanup / etc of CADisplayLink in Swift custom animation?
body: <p>Consider this trivial sync animation using <code>CADisplayLink</code>,</p>
  
  <pre><code>var link:CADisplayLink?
  var startTime:Double = 0.0
  let animTime:Double = 0.2
  let animMaxVal:CGFloat = 0.4
  
  private func yourAnim()
      {
      if ( link != nil )
          {
          link!.paused = true
          //A:
          link!.removeFromRunLoop(
            NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
          link = nil
          }
  
      link = CADisplayLink(target: self, selector: #selector(doorStep) )
      startTime = CACurrentMediaTime()
      link!.addToRunLoop(
        NSRunLoop.currentRunLoop(), forMode:NSDefaultRunLoopMode)
      }
  
  func doorStep()
      {
      let elapsed = CACurrentMediaTime() - startTime
  
      var ping = elapsed
      if (elapsed &gt; (animTime / 2.0)) {ping = animTime - elapsed}
  
      let frac = ping / (animTime / 2.0)
      yourAnimFunction(CGFloat(frac) * animMaxVal)
  
      if (elapsed &gt; animTime)
          {
          //B:
          link!.paused = true
          link!.removeFromRunLoop(
            NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
          link = nil
          yourAnimFunction(0.0)
          }
      }
  
  func killAnimation()
      {
      // for example if the cell disappears or is reused
      //C:
      ????!!!!
      }
  </code></pre>
  
  <p>There seems to be various problems.</p>
  
  <p>At (A:), even though <code>link</code> is not null, it may not be possible to remove it from a run loop.  (For example, someone may have initialized it with <code>link = link:CADisplayLink()</code> - try it for a crash.)</p>
  
  <p>Secondly at (B:) it seems to be a mess ... surely there's a better (and more Swift) way, and what if it's nil even though the time just expired?</p>
  
  <p>Finally in (C:) if you want to break the anim ... I got depressed and have no clue what is best.</p>
  
  <p>And really the code at A: and B: should be the same call right, kind of a clean-up call.</p>