无法将“NSLayoutConstraint”类型的不可变值作为 inout 参数传递

Posted

技术标签:

【中文标题】无法将“NSLayoutConstraint”类型的不可变值作为 inout 参数传递【英文标题】:Cannot pass immutable value of type 'NSLayoutConstraint' as inout argument 【发布时间】:2017-12-06 09:01:51 【问题描述】:

我尝试重新分配一个参考 NSLayoutConstraint。

class ViewController: UIViewController 
    @IBOutlet weak var myConstraint: NSLayoutConstraint!

    override func viewDidLoad() 
        super.viewDidLoad()
        exchangeConstraint(&myConstraint)
    


extension UIViewController 
    func exchangeConstraint(_ constraint: inout NSLayoutConstraint) 
        let spacing = constraint.constant
        view.removeConstraint(constraint)
        constraint = view.topAnchor.constraint(equalTo: anotherView.topAnchor, constant: spacing)
        view.addConstraint(constraint)
    

但在这里它给了我错误:

exchangeConstraint(&myConstraint)
-------------------^
Cannot pass immutable value of type 'NSLayoutConstraint' as inout argument

我不明白为什么它说不可变值,而约束被声明为变量,而不是常量。

【问题讨论】:

约束不是这样工作的。您需要删除旧约束并安装新约束(您可以修改常量属性,但不需要 inout 参数)。无论如何,您应该有充分的理由使用 inout 参数。如果这是你想要的,最好让函数返回一个新的约束。 是的,目前为了保持我的代码运行,我按照您的建议进行操作。所以myConstraint = doSomething(myConstraint)。我只是不喜欢在一行中使用该变量两次。我希望有一种更清洁的方式。 与使用副作用(inout 参数)相比,这是一种更简洁的方法。正如我所说,在添加新约束之前,无论如何您都需要删除现有约束,如果您没有对现有约束的引用,则很难做到这一点。 NSLayoutConstraint 无论如何都是引用类型。为什么将它作为inout 参数传递? 好的,我更新了我的示例。我想保留约束变量,但更改其内容。所以我从视图中删除它,为变量分配一个新值并再次添加它。 【参考方案1】:

我通过简单地将constraint 参数声明为显式解包NSLayoutConstraint 来解决它。

func exchangeConstraint(_ constraint: inout NSLayoutConstraint!) 
    ...

更新

这是我使用它的一个项目:https://github.com/truffls/compatible-layout-anchors-ios

【讨论】:

以上是关于无法将“NSLayoutConstraint”类型的不可变值作为 inout 参数传递的主要内容,如果未能解决你的问题,请参考以下文章

无法获取 NSLayoutConstraint 的约束

NSLayoutConstraint 设置

为啥我不能创建一个 NSLayoutConstraint 类型的数组? [复制]

在 NSLayoutConstraint 上更新“常量”失败,并显示“无法分配给 'constraint' 中的 'constant'”

NSInvalidUnarchiveOperationException:无法实例化名为 NSLayoutConstraint 的类

错误:NSInvalidUnarchiveOperationException:无法实例化名为 NSLayoutConstraint 的类