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

iOS 17下SwiftUI View及成员无法释放的内存泄漏问题

SwiftUI fullScreenCover 视图关闭后无法释放的内存泄漏问题

问题复现

以下代码在iOS 17及以上版本中,反复弹出并关闭CheckSecond视图时,控制台仅打印init,不会触发LogDeinit的deinit方法,内存图谱显示LogDeinit实例被SwiftUI内部对象持续引用,存在内存泄漏;但该代码在iOS 16中表现正常,每次关闭视图都会打印deinit。

@main
struct ExampleApp: SwiftUI.App {
    @State var show = false

    var body: some Scene {
        WindowGroup {
            VStack {
                Button("Present") { show = true }
                Text("First")
                    .fullScreenCover(isPresented: $show) {
                        CheckSecond { show = false }
                    }
            }
        }
    }
}

struct CheckSecond: View {
    private let log = LogDeinit()
    var action: () -> Void
    
    var body: some View {
        Text("Second")
        Button("Back"){ action() }
    }
}

class LogDeinit {
    init() { print("init") }    
    deinit { print("deinit") }
}

问题原因

原代码通过传递闭包action来控制弹窗关闭,该闭包捕获了ExampleApp中的@State变量show,在iOS 17+的SwiftUI内部实现中,这种闭包捕获方式可能引发循环引用,导致CheckSecond视图及其成员无法被正确释放。

解决方案

避免通过闭包传递关闭逻辑,改用@Binding直接绑定弹窗的显示状态,让子视图直接控制绑定变量的取值,消除闭包捕获带来的引用问题:

@main
struct ExampleApp: SwiftUI.App {
    @State var show = false

    var body: some Scene {
        WindowGroup {
            VStack {
                Button("Present") { show = true }
                Text("First")
                    .fullScreenCover(isPresented: $show) {
                        CheckSecond(isPresented: $show)
                    }
            }
        }
    }
}

struct CheckSecond: View {
    private let log = LogDeinit()
    @Binding var isPresented: Bool
    
    var body: some View {
        Text("Second")
        Button("Back"){
            isPresented = false
        }
    }
}

class LogDeinit {
    init() { print("init") }    
    deinit { print("deinit") }
}

修改后,每次关闭CheckSecond视图时,控制台会正常打印deinit,内存泄漏问题得到解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:57:48