在闭包中捕获结构引用不允许发生突变 [英] Capturing a struct reference in a closure doesn't allow mutations to occur

查看:139
本文介绍了在闭包中捕获结构引用不允许发生突变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图看看我是否可以使用结构体为我的模型,并尝试这个。当我调用 vm.testClosure(),它不会改变 x 的值,我不知道为什么。

  struct Model 
{
var x = 10.0
}


var m = Model()

class ViewModel
{
let testClosure :() - > ()

init(inout model:Model)
{
testClosure =
{
() ()in
model.x = 30.5
}
}
}



var vm = ViewModel & m)

mx

vm.testClosure()

mx

$ p>

解决方案<它只是一个值类型的影子拷贝,当函数返回时,它会写回调用者的值。



是你的 inout 变量是转义函数的生命周期(通过捕获在一个闭包,然后存储) - 意味着任何更改函数返回之后的inout 变量将永远不会反映在该闭包之外。



由于这个常见的误解, inout 参数,有是一个只允许 inout 参数被 @noescape 闭包捕获的Swift Evolution提议。从Swift 3开始,你当前的代码将不再编译。



如果你真的需要传递代码中的引用,那么你应该使用引用类型 Model a class )。虽然我怀疑你可能会重构你的逻辑,以避免传递引用首先(但没有看到你的实际代码,这是不可能建议)。


I am trying to see if I can use structs for my model and was trying this. When I call vm.testClosure(), it does not change the value of x and I am not sure why.

struct Model
{
    var x = 10.0
}


var m = Model()

class ViewModel
{
    let testClosure:() -> ()

    init(inout model: Model)
    {
        testClosure =
        {
            () -> () in
            model.x = 30.5
        }
    }
}



var vm = ViewModel(model:&m)

m.x

vm.testClosure()

m.x

解决方案

An inout argument isn't a reference to a value type – it's simply a shadow copy of that value type, that is written back to the caller's value when the function returns.

What's happening in your code is that your inout variable is escaping the lifetime of the function (by being captured in a closure that is then stored) – meaning that any changes to the inout variable after the function has returned will never be reflected outside that closure.

Due to this common misconception about inout arguments, there has been a Swift Evolution proposal for only allowing inout arguments to be captured by @noescape closures. As of Swift 3, your current code will no longer compile.

If you really need to be passing around references in your code – then you should be using reference types (make your Model a class). Although I suspect that you'll probably be able to refactor your logic to avoid passing around references in the first place (however without seeing your actual code, it's impossible to advise).

这篇关于在闭包中捕获结构引用不允许发生突变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆