Escaping closure captures 'inout' parameter

Viewed 1359

I have a function like below, but when I perform it , it's show "Escaping closure captures 'inout' parameter 'cani'" and i missing anything?

func duration(out:Int,h2:Int,rep:Int,cani:inout Bool){
        var io = 0
        var b  = 0
        cani = false
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { // "Escaping closure captures 'inout' parameter 'cani'" //
            timer in
            io += 1
            b  += 1
            if b <= out{
                    text = "come in"
            }else if b <= out + h2 && b > out{
                    text = "Hold on"
            }

            if io == (out + h2 ) * rep{
                textcange = "End"
                timer.invalidate()
                cani = true
            }
        }
}

it's show "Escaping closure captures 'inout' parameter 'cani'"

1 Answers

When you enter your function, the cani value is duplicated, when you exit the function, the duplicated value, potentially modified, is written back. That's what inout does.

Your function is asynchronous, so it exits immediately and cani is not modified.

When your timer closure is called, first you don't even know if the caller is still living, but you can be sure the cani copy that was passed does not exist anymore since the function has already exit a while ago.

The compiler detects this non-sense and tells you to do differently.

You may consider adding a cani property in the object that calls the timer, and changes its value in the timer closure or better, since it is asynchronous, call a closure do do what you want to do when the timer issues.

func duration(out:Int,h2:Int,rep:Int,cani:inout Bool){
    var io = 0
    var b  = 0
    var test: String

    Timer.scheduledTimer(withTimeInterval: 1.0, 
                         repeats: true,
                         completion: (String)->Void) {
        timer in
        io += 1
        b  += 1
        if b <= out {
            text = "Come in"
        } else if b <= out + h2 {
            text = "Hold on"
        }

        if io == (out + h2 ) * rep {
            text = "End"
            timer.invalidate()
            completion()
        }
    }
}

It's better to put simple and understandable code in StackOverflow questions. And if possible, buildable. ;)

Related