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

如何实现无内存泄漏的视图控制器重复工作流?

解决重复工作流的导航栈内存泄漏问题

核心思路

当C完成工作流要启动新的A时,直接把整个导航栈替换成新的A控制器,旧的A、B、C会因为失去强引用被自动回收,既保留当前工作流内的返回能力,又不会堆积历史控制器。

具体操作步骤

  • 替换导航栈,不用performSegue跳转
    在C控制器里,完成工作流后触发跳转的代码里,直接创建新的A实例,然后重置导航栈:

    // 假设A的storyboard ID是"AViewController"
    let newA = storyboard?.instantiateViewController(withIdentifier: "AViewController") as! AViewController
    navigationController?.setViewControllers([newA], animated: true)
    

    这个操作会把导航栈直接换成[newA],旧的A、B、C会被ARC自动清理,不会留在栈里占内存,而且animated: true能保留跳转动画,和用segue的体验一致。

  • 排查残留的_childModalViewController
    如果内存图里还能看到这个链,检查这两点:

    1. 有没有用present(_:animated:completion:)弹出过控制器但没调用dismiss(animated:completion:)?modal弹出的控制器如果不手动 dismiss,会一直被保留。
    2. 检查A、B、C里的闭包、代理有没有循环引用:比如代理没设成weak,或者闭包捕获了self但没加[weak self],导致控制器无法被销毁。可以在每个控制器的deinit里加打印日志,确认是否被回收:
      deinit {
          print("\(self) 被销毁了")
      }
      
      如果没看到对应打印,就说明有其他强引用没释放,得针对性排查。
  • 当前工作流内的返回不受影响
    B返回A、C返回B依然用系统默认的返回按钮或者popViewController(animated: true)就行,完全不影响,因为新工作流的栈是独立的。

内容的提问来源于stack exchange,提问作者The Beruriah Incident

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:33:22