title: Swift unowned self leaking when 'owned' by a view being presented
body: <p>I am experiencing a leak with unowned self under conditions where, to the best of my knowledge, there shouldn't be a leak. Let me show an example, it is a little contrived, so bear with me, I've tried to make the simplest case I could.</p>
  
  <p>Suppose I have a simple view controller that executes a closure on viewDidLoad:</p>
  
  <pre><code>class ViewController2: UIViewController {
  
      var onDidLoad: (() -&gt; Void)?
  
      override func viewDidLoad() {
          super.viewDidLoad()
          onDidLoad?()
      }
  }
  </code></pre>
  
  <p>and a class, ViewHandler, that owns an instance of this view controller and injects a call to a notify function into its closure, using an unowned reference:</p>
  
  <pre><code>class ViewHandler {
  
      private let viewController2 = ViewController2()
  
      func getViewController() -&gt; ViewController2 {
          viewController2.onDidLoad = { [unowned self] in
              self.notify()
          }
          return viewController2
      }
  
      func notify() {
          print("My viewcontroller has loaded its view!")
      }
  }
  </code></pre>
  
  <p>Then, when its view controller is presented by another view controller, the ViewHandler is leaking when nilled out:</p>
  
  <pre><code>class ViewController: UIViewController {
  
      private var viewHandler: ViewHandler?
  
      override func viewDidAppear(_ animated: Bool) {
          super.viewDidAppear(animated)
          viewHandler = ViewHandler()
          self.present(viewHandler!.getViewController(), animated: true, completion: nil)
  
          viewHandler = nil // ViewHandler is leaking here.
      }
  }
  </code></pre>
  
  <p>I know the example may seem a little contrived, but as far as I know there shouldn't be a leak. Let my try and break it down:</p>
  
  <p>Before presenting ViewHandler.ViewController2, ownership should look like this:</p>
  
  <pre><code>ViewController -&gt; ViewHandler -&gt; ViewController2 -|
                         ^                          |
                         |_ _ _ _ unowned _ _ _ _ _ |
  </code></pre>
  
  <p>After presenting ViewHandler.ViewController2, ownership should look like this:</p>
  
  <pre><code>         _______________________________
          |                               v
  ViewController -&gt; ViewHandler -&gt; ViewController2 -|
                         ^                          |
                         |_ _ _ _ unowned _ _ _ _ _ |
  </code></pre>
  
  <p>After nilling out ViewHandler, ownership should look like this:</p>
  
  <pre><code>         _______________________________
          |                               v
  ViewController    ViewHandler -&gt; ViewController2 -|
                         ^                          |
                         |_ _ _ _ unowned _ _ _ _ _ |
  </code></pre>
  
  <p>Nothing is owning ViewHandler and it should be released. However this is not the case and ViewHandler is leaking.</p>
  
  <p>If I change the reference in the capture list of the closure injected into onDidLoad to weak, there is no leak and ViewHandler is released as expected:</p>
  
  <pre><code>func getViewController() -&gt; ViewController2 {
      viewController2.onDidLoad = { [weak self] in
          self?.notify()
      }
      return viewController2
  }
  </code></pre>
  
  <p>Also, something I can't explain, if I keep the reference as unowned and make ViewHandler inherit from NSObject, ViewHandler is released as expected and there is no leak:</p>
  
  <pre><code>class ViewHandler: NSObject {
  
      private let viewController2 = ViewController2()
  
      func getViewController() -&gt; ViewController2 {
          viewController2.onDidLoad = { [unowned self] in
              self.notify()
          }
          return viewController2
      }
  
      ....
  }
  </code></pre>
  
  <p>Anyone who can explain what going on?</p>