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

如何解决等待Completion Handler回调时视图控制器无法释放的问题

iOS URLSession 逃逸闭包导致控制器内存泄漏解决方案

问题核心是@escaping 逃逸闭包强持有视图控制器,形成循环引用,导致控制器无法被正常释放。可通过以下两步组合解决:

  • 在逃逸闭包的捕获列表中添加[weak self]打破强引用循环
    逃逸闭包默认会强持有所有捕获的外部对象,若直接在闭包内部使用self,只要闭包未执行完成,控制器就会被一直持有无法释放。添加[weak self]后,闭包对控制器的引用变为弱引用,不会阻碍控制器的释放。
    可在闭包开头先判断self是否存在,若控制器已经销毁直接终止后续逻辑,避免不必要的资源消耗。

  • 主动管理未完成的网络请求
    仅添加弱引用仅解决了内存泄漏问题,未完成的网络请求依然会在后台执行,浪费流量和系统资源。你可以将发起的URLSessionDataTask存为控制器的私有属性,在控制器deinit方法中主动取消未完成的请求。

完整示例代码

class CustomViewController: UIViewController {
    // 存储当前正在执行的网络任务
    private var currentDataTask: URLSessionDataTask?

    // 按钮点击触发的加载逻辑
    func clickLoadButton() {
        guard let targetUrl = URL(string: "你的请求地址") else { return }
        // 发起请求并保存任务实例
        currentDataTask = URLSession.shared.dataTask(with: targetUrl) { [weak self] data, response, error in
            // 控制器已销毁,直接返回不处理后续逻辑
            guard let self = self else { return }
            // 原有业务逻辑处理
            if let data = data {
                DispatchQueue.main.async {
                    // 刷新UI等操作
                }
            }
        }
        currentDataTask?.resume()
    }

    deinit {
        // 控制器销毁前主动取消未完成的网络请求
        currentDataTask?.cancel()
    }
}

注意:尽量不要使用[unowned self]替代[weak self],如果闭包执行时控制器已经销毁,unowned引用会触发野指针崩溃,[weak self] + 可选绑定的写法兼容性和安全性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:12:00