Roi Mulia
Roi Mulia

Reputation: 5896

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! :)

Upvotes: 1

Views: 919

Answers (2)

shallowThought
shallowThought

Reputation: 19602

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)

Upvotes: 2

Connor Neville
Connor Neville

Reputation: 7361

Your actions take no parameters and don't return anything, so they'll be of the type:

var action: (() -> ())
// or, if you want action to be optional:
var action: (() -> ())?

EDIT: I originally wrote that you should use [weak self] to avoid retain cycles as I didn't notice action was declared inside a function. Since it's inside a function, action will deallocate once the function is done, so there is no retain cycle.

Upvotes: 0

Related Questions