逃逸闭包捕获了'inout'参数

4
我有一个类似下面的函数,但当我执行它时,显示“逃逸闭包捕获'inout'参数'cani'”,我有什么遗漏吗?
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
            }
        }
}

显示 "逃逸闭包捕获'inout'参数'cani'"


你检查了这些类似的问题吗?https://dev59.com/3VkS5IYBdhLWcg3wp4XO,https://dev59.com/dkQEtIcB2Jgan1zn-Q2_,https://stackoverflow.com/q/50282040/1187415 - Martin R
1个回答

4

当您输入函数时,cani值会被复制一份,在退出函数时,复制的值可能会被修改并写回。这就是inout的作用。

由于您的函数是异步的,因此它立即退出,cani不会被修改。

当您的定时器闭包被调用时,首先您甚至不知道调用者是否仍然存在,但是您可以确定传递的cani副本已经不存在了,因为函数已经退出了一段时间。

编译器会检测到这种错误,并告诉您要以不同的方式操作。

您可以考虑在调用定时器的对象中添加一个cani属性,并在定时器闭包中更改其值,或者更好的做法是,由于它是异步的,调用闭包来执行您想要执行的操作。

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()
        }
    }
}

在 StackOverflow 的问题中最好放置简单易懂的代码,并且如果可能,可以构建它。 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接