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

SwiftUI中类引发循环引用:如何解决视图无法销毁的问题

打破SwiftUI中View与ObservableObject的循环引用方案

针对你遇到的循环引用问题,这里提供几种可行的解决方案:

方案一:在View消失时清空闭包引用

利用onDisappear回调,在View即将销毁时清空MyObject中持有的闭包,直接打破循环链:

class MyObject: ObservableObject {
    var function = { () }
}

struct MyView: View {
    @State var value: Int = 0
    @StateObject var obj = MyObject()

    func viewMethod() { value += 1 }
    
    var body: some View {
        Text("Placeholder")
            .onAppear {
                obj.function = { self.viewMethod() }
            }
            .onDisappear {
                // 清空闭包,解除对View的引用
                obj.function = {}
            }
    }
}

这种方式简单直接,适合View和MyObject生命周期绑定的场景(比如MyObject由@StateObject管理,和View同生共死)。

方案二:使用无主引用(Unowned)捕获View

因为@StateObject管理的MyObject生命周期和View完全一致,不会出现View已销毁但MyObject还存在的情况,所以可以用unowned修饰捕获的self,避免闭包强引用View:

class MyObject: ObservableObject {
    var function = { () }
}

struct MyView: View {
    @State var value: Int = 0
    @StateObject var obj = MyObject()

    func viewMethod() { value += 1 }
    
    var body: some View {
        Text("Placeholder")
            .onAppear {
                // 用unowned self避免强引用
                obj.function = { [unowned self] in self.viewMethod() }
            }
    }
}

注意:仅当你能确保闭包调用时View一定存在的情况下使用unowned,否则可能触发崩溃。

方案三:将View逻辑转移到独立ViewModel类

如果View中的业务逻辑复杂,可将需要触发的方法和状态转移到独立的ViewModel类中,通过弱引用捕获ViewModel来打破循环:

class MyObject: ObservableObject {
    var function = { () }
}

// 独立ViewModel类,管理View的状态和方法
class ViewModel: ObservableObject {
    @Published var value: Int = 0
    
    func viewMethod() {
        value += 1
    }
}

struct MyView: View {
    @StateObject var vm = ViewModel()
    @StateObject var obj = MyObject()
    
    var body: some View {
        Text("Placeholder")
            .onAppear {
                // 弱引用捕获ViewModel,避免循环
                obj.function = { [weak vm] in
                    vm?.viewMethod()
                }
            }
    }
}

这种方式隔离了View和业务逻辑,同时通过weak vm避免了强引用循环,适合更复杂的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:41:12