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

导航链接跳转倒计时计时器视图触发Thread 1运行时崩溃错误

问题分析与修复方案

崩溃原因排查

你遇到的EXC_BAD_ACCESS错误主要来自两个核心问题:

  1. 视图结构语法错误:body中直接返回了VStack和HStack两个独立视图,SwiftUI要求body必须返回单个View,这种写法会导致底层视图渲染时的内存访问异常。
  2. Timer提前触发风险:Timer.publish设置了autoconnect(),会在视图初始化时立刻启动,此时如果ViewModel的time属性未完成初始化,调用updateCountdown就可能触发野指针访问。

修复后的完整代码

struct SlideFiveView: View {
    
    var time: Int
    
    @StateObject private var vm = ViewModel()
    // 先不自动连接Timer,手动控制启动时机
    private let timer = Timer.publish(every: 1, on: .main, in: .common)
    private let width: Double = 250
    // 用变量存储Timer订阅,控制生命周期
    @State private var timerCancellable: AnyCancellable?
    
    var body: some View {
        // 用根VStack包裹所有子视图,符合SwiftUI的View要求
        VStack(spacing: 30) {
            SlideOne()
            
            Text("\(vm.time)")
                .font(.system(size: 70, weight: .medium, design: .rounded))
                .padding()
                .frame(width: width)
                .background(.thinMaterial)
                .cornerRadius(20)
                .overlay(RoundedRectangle(cornerRadius: 20) // 补全链式调用的点号
                    .stroke(Color.gray, lineWidth: 4))
            //.alert("Timer done!", isPresented: $vm.showingAlert)
            
            HStack(spacing: 50) {
                Button("Start") {
                    vm.start(minutes: Float(time))
                    // 点击Start后再启动Timer
                    timerCancellable = timer.autoconnect().sink { _ in
                        vm.updateCountdown()
                    }
                }
                
                Button("Pause") {
                    // 支持暂停,取消Timer订阅
                    timerCancellable?.cancel()
                }
            }
        }
        .onDisappear {
            // 视图消失时取消Timer,避免内存泄漏
            timerCancellable?.cancel()
        }
    }
}

// 补充ViewModel的标准实现(确保属性初始化正确)
class ViewModel: ObservableObject {
    @Published var time: Int = 0
    @Published var showingAlert = false
    private var totalSeconds: Int = 0
    
    func start(minutes: Float) {
        totalSeconds = Int(minutes * 60)
        time = totalSeconds
    }
    
    func updateCountdown() {
        guard totalSeconds > 0 else {
            showingAlert = true
            return
        }
        totalSeconds -= 1
        time = totalSeconds
    }
}

关键修复点

  • 修复视图结构:用根VStack包裹所有子视图,确保body返回单个View,解决底层渲染的内存异常。
  • Timer手动控制:移除autoconnect(),改为点击Start后再订阅Timer,避免视图初始化时Timer提前触发访问未初始化的ViewModel属性。
  • 语法错误修正:补全overlay前的点号,确保链式调用正常工作。
  • 内存管理优化:用AnyCancellable管理Timer订阅,视图消失时取消订阅,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:10:51