Swift中如何在类与视图间保持AudioRecorder对象状态不丢失?
解决SwiftUI中跨视图保持AudioRecorder状态的问题
你的核心问题是跳转至RatingView时新建了全新的AudioRecorder实例,而非传递之前已经完成录制的那个实例,导致原有startTime、stopTime的状态完全丢失。以下是具体的修复方案:
1. 传递已有AudioRecorder实例而非新建
在RecorderView的NavigationLink中,把你当前持有的audioRecorder实例传递给RatingView,而不是创建新的:
// 替换RecorderView中的NavigationLink代码 if showRatingView == true { NavigationLink( destination: RatingView(rating: 1, audioRecorder: audioRecorder), isActive: self.$showRatingView ) { EmptyView() } }
2. 修正AudioRecorder的状态定义与方法
当前AudioRecorder的startTime和stopTime是非可选的Date类型,但未初始化,这会导致编译错误,同时不符合“录制前无时间值”的业务逻辑。另外saveToCoreData方法中直接使用未定义的moc也是问题,需要修正:
class AudioRecorder: NSObject, ObservableObject { @Published var startTime: Date? // 改为可选类型,录制前为nil @Published var stopTime: Date? @Published var recording = false // 补充你原代码中用到的recording状态 func startRecording() { self.startTime = Date() self.recording = true // 此处添加实际录制逻辑 } func stopRecording() { self.stopTime = Date() self.recording = false // 此处添加停止录制逻辑 } func saveToCoreData(rating: Int16, moc: NSManagedObjectContext) { // 先校验录制时间是否存在,避免空值崩溃 guard let startTime = startTime, let stopTime = stopTime else { print("错误:未完成录制,无法保存数据") return } let aRec = AudioRec(context: moc) aRec.uuid = UUID() aRec.startTime = startTime aRec.stopTime = stopTime aRec.rating = rating do { try moc.save() } catch { print("保存数据失败:\(error.localizedDescription)") } } }
3. 在RatingView中正确调用保存方法
修改RatingView的按钮动作,将环境中的Core Data上下文传递给saveToCoreData方法:
struct RatingView: View { @Environment(\.managedObjectContext) var moc @State var rating: Int16 @ObservedObject var audioRecorder: AudioRecorder @State private var displayNewView: Bool = false var body: some View { VStack { Text("How was the recording experience?") // 这里可以添加你的评分选择控件,比如将@State rating改为绑定值实现交互 Button(action: { audioRecorder.saveToCoreData(rating: rating, moc: moc) // 保存完成后可根据需求跳转或返回 displayNewView = true }) { Text("Submit Response") } } .navigationBarBackButtonHidden(true) } }
关键注意点
- 始终在视图间传递同一个
ObservableObject实例,保证状态的连续性 - 用可选类型合理表示“未初始化”的状态,避免不必要的默认值
- 不要在业务类(如
AudioRecorder)中直接持有Core Data上下文,通过视图的环境变量传递更符合SwiftUI的设计逻辑 - 添加必要的校验与错误处理,避免因异常状态导致崩溃
内容的提问来源于stack exchange,提问作者JJ123
相关产品推荐
相关产品推荐

