3

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'"

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Did you check these similar questions? https://stackoverflow.com/q/39569114/1187415, https://stackoverflow.com/q/59943008/1187415, https://stackoverflow.com/q/50282040/1187415 – Martin R Jan 28 '22 at 07:47

1 Answers1

3

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. ;)

Moose
  • 2,607
  • 24
  • 23