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

Swift中 Dismiss ViewController 后内存未释放问题咨询

解决重复跳转ViewController后的内存泄漏问题

兄弟,这种反复打开再关闭DetailViewController后内存持续飙升的情况,我踩过好多次坑,大概率是循环引用或者页面内的资源没及时清理导致的,咱们一步步来排查解决:

1. 先排查最常见的循环引用问题

循环引用会直接导致DetailViewController的deinit方法无法执行,内存永远释放不了,优先检查这几点:

  • 闭包中的强引用:如果你的DetailViewController里有网络请求、异步回调这类闭包代码,一定要用[weak self]或者[unowned self]打破循环:
    // 错误示例(会导致循环引用)
    APIManager.loadDetailData { result in
        self.refreshUI(with: result)
    }
    
    // 正确写法
    APIManager.loadDetailData { [weak self] result in
        self?.refreshUI(with: result)
    }
    
  • 代理的强引用:如果DetailViewController用到了代理模式,必须把代理声明为weak类型,因为UIViewController是引用类型,强引用代理会导致双向持有:
    // 正确的代理声明方式
    protocol DetailViewControllerDelegate: AnyObject {
        func didFinishDetailOperation()
    }
    
    class DetailViewController: UIViewController {
        weak var delegate: DetailViewControllerDelegate?
    }
    

2. 检查页面内的资源是否及时释放

即使没有循环引用,如果页面内的资源没主动清理,也会导致内存占用居高不下:

  • 定时器(Timer):如果用了Timer,一定要在页面销毁前调用invalidate(),最好放在deinit里:
    class DetailViewController: UIViewController {
        var timer: Timer?
    
        deinit {
            timer?.invalidate()
            timer = nil
            print("DetailViewController 已销毁")
        }
    }
    
  • 通知观察者:如果通过NotificationCenter注册了通知,一定要在deinit里移除观察者:
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
  • 网络/下载任务:如果有未完成的URLSession任务,要在页面销毁前取消并置空引用:
    class DetailViewController: UIViewController {
        var dataTask: URLSessionDataTask?
    
        deinit {
            dataTask?.cancel()
            dataTask = nil
        }
    }
    

3. 用Xcode工具精准定位泄漏点

如果上面的方法还没解决,直接用Xcode的Leaks工具排查:

  1. 打开Xcode,点击顶部菜单 Product > Profile(快捷键Command + I)
  2. 在弹出的窗口中选择Leaks,点击Choose
  3. 运行App后,重复你的跳转操作50次左右,看Leaks面板里的红色标记,点击进去就能看到具体哪个对象没被释放,以及它的引用链,顺着链就能找到泄漏根源。

最后确认一个小细节

确保你在DetailViewController里调用的是正确的关闭方法:

// 正确的dismiss方式(如果是用present打开的)
@objc func backButtonTapped() {
    dismiss(animated: true)
}

不要混用push/pop和present/dismiss,否则可能导致页面栈混乱,间接引发内存问题。

内容的提问来源于stack exchange,提问作者Emre Önder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:07:03