Don't understand the closure usage in Coordinate/State management pattern

44 Views Asked by At

I've come across this strange closure usage in the link

The below code is a simplified version in Xcode Playground

typealias AppStateDeeplinkAction   = () -> ()

var deeplinkBlock : AppStateDeeplinkAction? = {
    print ("this is for deeplink")
}

func deeplinkAction() {
    if let deeplinkAction = deeplinkBlock {
        print("deeplink is executed")
        deeplinkAction() // <- if this is commented out, the result is just "deeplink is executed"
    }
}

deeplinkAction() 

The result of this is,

deeplink is executed
this is for deeplink

What's confusing is, deeplinkAction() func is called inside the if-let and there is no compile/run time error. It ended up successfully. What I don't get quite is the recursive call of deeplinkAction().

Compared to this, if deeplinkAction() is commented out, the result is just

deeplink is executed

What kind of 'closure' feature am I missing? How should I interpret this?

1

There are 1 best solutions below

0
Dávid Pásztor On

There's no recursive call here, but using the same name for an optional binded closure variable as for the enclosing function is misleading and hence a bad idea.

Simply rename it and everything will be clear. The parentheses after a closure variable execute said closure, so deeplinkBlock() execute the closure stored in the deeplinkBlock variable.

typealias AppStateDeeplinkAction = () -> ()

var deeplinkBlock : AppStateDeeplinkAction? = {
    print ("this is for deeplink")
}

func deeplinkAction() {
    if let deeplinkBlock = deeplinkBlock {
        print("deeplink is executed")
        deeplinkBlock()
    }
}

deeplinkAction() 

Actually, there's no need for the optional binding anyways, you can use optional chaining on closures too.

func deeplinkAction() {
    deeplinkBlock?()
}