Search code examples
swiftswift3closuresblockretain-cycle

Storing Block of code inside variable


It's pretty simple, i'm sure i'm missing something.

I'm trying to understand how to achieve the following: action should "hold" a block of code, that i will eventually execute inside UIView.animate (for example).

What is the right way? + Should i be worried about using self. in terms of retain-cycle inside action closure?

Sample function :

func forward(_ sender : UIButton) {

 var action : <Clousre of somekind?>

 switch currentPosition
  {
   case 0 : action = { self.view.background = .red }
   case 1 : action = { self.view.background = .blue }
   default : fatalError("No current Position")
  }

 UIView.animate(withDuration: 1, animations: {
    action
  })
 }

Thanks! :)


Solution

  • Declare it like this:

    var action: () -> Void
    

    There is no retain cycle.

    self does not hold a reference to action.

    If action would be a property (outside the function) there would be a retain cycle:

    self.action <--> action = { self... }

    Put together:

    var action : () -> Void
    
    switch currentPosition {
        case 0 : action = { /*do something*/ }
        case 1 : action = {  /*do something*/ }
        default : fatalError("No current Position")
    }
    
    UIView.animate(withDuration: 1, animations: {
        action()
    })
    
    // or
    
    UIView.animate(withDuration: 1, animations: action)
    

    (compiles fine in Playground)