You need to enable JavaScript to run this app. 跨多控制器注册流程中临时用户数据存储及单例使用最佳实践
优惠活动
大模型
产品
解决方案
定价
更多

跨多控制器注册流程中临时用户数据存储及单例使用最佳实践

现有实现的核心问题排查

你的初步代码存在两处会导致注册流程完全跑不通的硬伤:

  • Patient类的实现逻辑闭环失效:你把Patient的初始化器设为私有,同时在类内部定义了let shared = Patient()作为类内部单例,但外部完全没有权限创建Patient实例赋值给AppSession.currentPatient属性,所有文本框输入的赋值操作会因为可选链断开完全不生效
  • 单例的使用场景错位:你要存储的是单次注册流程的临时用户数据,不是需要全局常驻的登录态用户信息,把Patient本身做成单例会导致残留脏数据——用户中途退出注册再重新进入时,会读到上半次没提交的旧数据
适配当前注册流程的方案选型

针对“3-4个控制器需要共享临时录入数据、流程结束后才写入Realm”的场景,两种可行方案的适配度对比如下:

方案1:流程级上下文容器(推荐)

这种方案的核心是把临时数据的生命周期绑定到整个注册导航栈,而不是整个App的生命周期,从根源上避免脏数据跨场景污染:

  • 实现逻辑:在注册流程的根节点创建一个专属的上下文容器,导航过程中所有子控制器直接持有这个容器的引用读取、修改临时数据,当整个注册流程结束(提交成功写入Realm/用户主动取消注册)、导航栈被销毁时,容器和临时数据会随引用计数归0自动释放,不需要手动维护状态清理逻辑
  • 参考实现代码:
// 注册流程专属上下文,非全局单例
struct RegistrationFlowContext {
    // 存储临时录入的用户数据
    var tempPatient = Patient()
    // 流程结束的回调逻辑,比如提交数据写入Realm
    var onFlowFinish: ((Patient) -> Void)?
}

// 纯数据模型Patient
struct Patient {
    var name: String = ""
    var weight: Double = 0.0
    var bodyMeasurements: [String: Double] = [:]
}
  • 子控制器传值逻辑:在每个注册阶段的视图控制器初始化时,把上下文实例作为依赖传入,跳转页面时直接把上下文顺着导航栈传递即可,不需要跨页面读取全局状态:
// 从姓名录入页跳转到体重录入页时,直接携带上下文
let weightVC = WeightInputViewController(flowContext: context)
navigationController?.pushViewController(weightVC, animated: true)
  • 文本框赋值逻辑:
// 直接修改上下文里的临时数据
flowContext.tempPatient.name = inputText

方案2:全局会话容器(可作为备选)

如果不想逐层传递上下文实例,也可以使用全局单例存储临时数据,但必须修正之前的错误实现,避免状态不可控:

  • 修正后的单例代码:
final class AppSession {
    static let shared = AppSession()
    private init() {}
    
    // 存储当前正在注册流程中的临时患者数据
    var currentRegisteringPatient: Patient?
    
    // 统一的状态重置方法,从入口层避免脏数据残留
    func resetRegisteringFlowData() {
        currentRegisteringPatient = nil
    }
}

// 注意:Patient不需要实现私有初始化器、不需要类内单例,仅作为普通数据模型承载属性即可
struct Patient {
    var name: String = ""
    var weight: Double = 0.0
}
  • 落地的强制校验点:
    • 每次进入注册流程的首个页面时,必须先调用resetRegisteringFlowData()方法清空旧状态,再初始化新的Patient实例赋值给属性,避免读到历史注册流程的残留数据
    • 所有录入数据完成Realm持久化、整个注册流程跳转完成后,必须再次调用重置方法清空临时数据,释放内存
模型类型选择:类还是结构体

优先用结构体实现Patient模型:

  • 当前场景下存储的是姓名、体重、人体测量值这类纯输入数据,不需要跨场景共享的引用语义,结构体的值拷贝特性可以避免多个控制器因为持有同一个类实例的引用,出现非预期的跨页面数据修改问题
  • 只有当模型需要绑定实时输入回调、或者需要和Realm的持久化模型做类型映射适配时,再考虑用类实现即可,临时注册数据场景没有强制用类的必要性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 09:45:03