You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

双ViewController应用内存持续增长,如何正确管理内存避免崩溃?

解决ViewController切换时内存持续累加的问题

从你描述的内存持续上涨、切换回第一个ViewController后内存无法回落的情况来看,这显然是内存泄漏导致的——第二个ViewController(简称VC2)及其关联的资源(地图组件、标注点、JSON数据等)在你返回第一个VC(VC1)时没有被系统正确回收,每次进入VC2都会新增一份内存占用,反复几次就会触发崩溃。下面给你一套具体的排查和解决步骤:

1. 先确认VC2是否真的被销毁

首先在VC2的deinit方法里加个打印,验证它是否在返回VC1时被释放:

deinit {
    print("VC2 已被销毁")
}

如果切换回VC1后看不到这个打印,说明VC2被某个强引用“抓着”不肯放,这是核心问题。常见的强引用来源有这几个:

  • 地图代理的循环引用:MKMapView会强持有它的delegate,如果你的VC2直接把self设为代理(mapView.delegate = self),而VC2又强持有mapView,就形成了循环引用,双方都无法释放。
    解决方法:在VC2的deinit里手动置空代理,或者把代理声明为弱引用:

    deinit {
        mapView.delegate = nil // 关键:打破循环引用
    }
    
  • 闭包捕获了强引用的self:如果加载JSON数据或者处理地图逻辑时用了闭包,比如URLSession的请求闭包,一定要用[weak self]避免捕获强引用:

    func loadJSONAnnotations() {
        URLSession.shared.dataTask(with: jsonURL) { [weak self] data, _, error in
            guard let self = self else { return }
            // 处理JSON数据、添加标注点的逻辑
        }.resume()
    }
    

2. 清理地图组件的关联资源

即使VC2能被销毁,地图上的标注点、自定义视图如果没清理,也可能残留内存占用:

  • 在VC2离开屏幕时(比如viewWillDisappear)或者deinit里,移除所有自定义标注点(注意保留用户位置标注):
    func cleanMapAnnotations() {
        let customAnnotations = mapView.annotations.filter { !($0 is MKUserLocation) }
        mapView.removeAnnotations(customAnnotations)
    }
    
  • 如果你的标注点用了自定义的MKAnnotationView,也要确保这些视图没有被其他全局对象持有,必要时可以在移除标注时手动销毁视图资源。

3. 检查JSON数据的持有方式

如果加载的JSON数据比较大,不要把它存在全局变量或者静态属性里,也不要让VC2以外的对象强持有这份数据。在VC2的deinit里手动置空数据引用:

deinit {
    self.jsonData = nil // 释放大对象引用
    mapView.delegate = nil
    cleanMapAnnotations()
    print("VC2 已销毁,内存释放")
}

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

如果上面的通用方法没解决问题,用Xcode的调试工具找具体泄漏对象:

  • Memory Graph Debugger:运行应用后点击调试栏里的“内存图调试”图标(方块带箭头的那个),切换几次VC后,查看内存中是否存在多个VC2的实例——如果有,说明每次进入都创建了新实例但旧的没释放,顺着引用链找是谁在持有它。
  • Leaks Instrument:打开Xcode的Product > Profile,选择Leaks模板,运行应用并反复切换VC,工具会标记出泄漏的对象,点击可以查看详细的引用关系,针对性修复。

总结

内存累加的本质是“本该被释放的对象没被释放”,核心排查方向就是:确保VC2的deinit能被调用(打破循环引用),清理所有关联的资源(地图代理、标注、数据),用工具定位具体的泄漏点。按照这个思路调整代码后,应该就能解决内存持续上涨的问题了。

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

火山引擎 最新活动