What is escaping meaning.


First of all, Closure! is block style’s “function type”.
and above Swift 3.0, Closure have default behavior as ‘non-escaping’.
because ‘non-escaping’ has more benefit of memory management.

  1. What is ‘non-escaping’?
    • ‘non-escaping’ closure has same behavior any other local properties in its function.

      summary
      1) timing side: Executed at called time exactly.
      2) memory side: Released when function was returned.
      func main() {
       // 1. Call function.
       sum { [weak self] result in
         // 4. Result closure block executed.
         print(result)
       }
      }
      func sum(result: ((Int) -> ())) {
       // 2. Do something.
       var sum = 0
       for value in [1, 2, 3] {
         sum += value
       }
       // 3. result closue called.
       result(sum)
       // 5. Funcion was returned.
      }
      


  2. What is ‘escaping’?
    • ‘escaping’ closure is can say it’s like stored global/member property.
      so, there is two typical situation you need to annotate “escaping” when using closure.
      first. no guarantee of when closure called as timing side.
      second. you want to save closure as global/member property as memory side.

      summary
      1) timing side: May be executed after function was returned. (network, delay, async…)
      func main() {
       // 1. Call function.
       sum { [weak self] result in
         // 4. Result closure block executed.
         print(result)
       }
      }
      func sum(result: @escaping ((Int) -> ())) {
       // 2. Do something.
       var sum = 0
       for value in [1, 2, 3] {
         sum += value
       }
       // 3. Delay called optional result closure.
       DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
         result(sum)
       }
      }
      

      2) memory side: Closure memory was no released than stored as global/member property.

      var storedClosure: ((Int) -> ())!
      func main() {
       // 1. Call function.
       sum { [weak self] result in
         print(result)
       }
      }
      func sum(result: @escaping ((Int) -> ())) {
       // 2. Do something.
       var sum = 0
       for value in [1, 2, 3] {
         sum += value
       }
       // 3. Assign result closure to storedClosure.
       storedClosure = result
      }
      


  3. What about optional closure?
    • Optional closure is equal to escaping closure.
      technically, optional closure is enum type not function type.
      means it can be any type.
      so, ‘swift’ define optional closure has annotation of escaping implicitly.
      func main() {
       // 1. Call function.
       sum { [weak self] result in
         // 4. Result closure block executed.
         print(result)
       }
      }
      func sum(result: ((Int) -> ())?) {
       // 2. Do something.
       var sum = 0
       for value in [1, 2, 3] {
         sum += value
       }
       // 3. Delay called optional result closure.
       DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
         result?(sum)
       }
      }