9

Swift Closure will have a strong reference cycle when it refers to self like this example:

class Test {
  var name = "Hello"

  func doSomething() {
    {() -> Void in 
      self.name = "otherName"
    }()
  }

}

In the previous example, I created a strong reference cycle so I have to fix it with:

class Test {
  var name = "Hello"

  func doSomething() {
    {[unowned self] () -> Void in 
      self.name = "otherName"
    }()
  }

} 

Question: If I refer self in a closure do I have to use alway unowned self or are there cases where I have to use weak self?

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
  • 2
    The closure is non-escaping (meaning the closure isn't asyncronous or doesn't have a delay so that it could 'stay in scope'). You don't need to use either of them. See [escaping vs non-escaping](https://swiftunboxed.com/lang/closures-escaping-noescape-swift3/). For an example of where you need to use one, see [here](https://stackoverflow.com/questions/32665326/reference-to-property-in-closure-requires-explicit-self-to-make-capture-seman/40530556#40530556) – mfaani Jul 09 '17 at 13:55

1 Answers1

17

If I refer self in a closure do I have to use alway unowned self or are there cases where I have to use weak self?

Neither. In most cases, just refer to self normally and do nothing with its memory management. You only have to worry about memory management if there is a danger of a retain cycle, and unless you store the closure somewhere, such as a property of self, there is no such danger.

You can easily prove this by adding a deinit implementation:

class Test {
    var name = "Hello"

    func doSomething() {
        {() -> Void in
            self.name = "otherName"
            }()
    }
    deinit {
        println("bye")
    }
}

Now make a Test instance and immediately release it:

func testTest () {
    let t = Test()
}

You see "bye" in the console, proving that the instance was released in good order. There was never any kind of "strong reference cycle" in this code. Your concerns are groundless.

[By the way, you are using the word "closure" wrong. Every Swift function is a closure. If there were a retain cycle issue merely because of using the word self in a closure, every Swift function would be subject to this issue - and clearly that is not the case. The place where weak and unowned self comes into play is in an anonymous function - and only, as I said before, if that anonymous function is itself also retained by self.]

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • For situations where a retain cycle _can_ arise, and on the difference between `weak` and `unowned`, see my book: http://www.apeth.com/swiftBook/ch05.html#_memory_management – matt May 03 '15 at 16:44
  • Could you give an example when to use it and when not to use it please? –  May 03 '15 at 16:45
  • See the link I just gave you! – matt May 03 '15 at 16:46
  • 1
    And in particular this section: http://www.apeth.com/swiftBook/ch05.html#SECweakSelf – matt May 03 '15 at 16:48