You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI视图中设置计算属性报错,如何正确调用setter?

解决SwiftUI中计算属性Setter调用的编译器错误

我来帮你搞定这个问题~你遇到的Cannot assign to property: 'self' is immutable错误,本质原因是SwiftUI的View是值类型(struct),默认在onTapGesture这类闭包里的self是不可变的(相当于let常量),而你的计算属性s的setter会修改视图内部的@State状态,不可变的self不允许执行这种修改操作。

下面给你两种可行的解决方法:

方法一:给计算属性Setter添加mutating关键字

把计算属性的setter标记为mutating,然后在闭包里创建一个可变的视图实例来修改,最后赋值回self触发视图更新:

struct Test: View{
    @State var _s = "test"
    @State var _s2 = true
    private var s : String {
        get { _s }
        // 给setter加上mutating关键字,允许修改self状态
        mutating set (new) {
            _s = "no test"
            _s2 = false
            // 这里可以继续添加其他逻辑
        }
    }
    var body: some View {
        Text("\(s)")
            .onTapGesture {
                // 创建可变的视图实例
                var mutableView = self
                mutableView.s = "anything"
                // 将修改后的实例赋值回self,触发SwiftUI重新渲染
                self = mutableView
            }
    }
}

方法二:提取状态修改逻辑为独立方法(更推荐)

看你的代码,setter里并没有用到传入的new参数,只是固定修改_s和_s2,这种情况下把逻辑抽成普通方法更清晰。而且@State属性的实际存储由SwiftUI框架管理,即使self不可变,也能直接修改它们的wrappedValue:

struct Test: View{
    @State var _s = "test"
    @State var _s2 = true
    // 只保留getter,或者直接用_s也可以
    private var s : String {
        get { _s }
    }
    
    // 把原来setter里的逻辑提取成方法
    private func updateViewState() {
        _s = "no test"
        _s2 = false
        // 这里可以添加其他需要执行的逻辑
    }
    
    var body: some View {
        Text("\(s)")
            .onTapGesture {
                // 直接调用方法修改状态即可
                updateViewState()
            }
    }
}

如果你的setter需要用到传入的new值,方法一完全适用;如果后续状态逻辑更复杂,也可以考虑用@Binding或自定义属性包装器,但这两种简单方法已经能解决当前问题啦~

内容的提问来源于stack exchange,提问作者mica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:17:45