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

ATTrackingManager.requestTrackingAuthorization是否需用[weak self]避免内存泄漏?

如何判断ATTrackingManager.requestTrackingAuthorization回调是否需要用[weak self]避免内存泄漏

核心结论

必须使用[weak self],否则会导致内存泄漏或不必要的内存占用

判断逻辑(通用闭包内存泄漏排查方法)

判断闭包是否需要弱引用self,核心看两个关键点:

  • 闭包的持有周期:ATTrackingManager.requestTrackingAuthorization的完成回调会被系统持有,直到用户处理授权弹窗(允许/拒绝)或系统自动完成授权流程,这个过程可能持续数秒甚至更久(比如用户一直不操作弹窗)。
  • 闭包与self的引用关系:如果闭包强引用self,会形成「self → 闭包(self的方法创建了闭包)」+「闭包 → self(强引用)」的潜在循环,或者在self已经不需要存在时(比如ViewController被销毁),闭包仍持有self导致无法释放。

结合你的代码示例分析

未使用[weak self]的风险

ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
    // 闭包强引用self,只要授权流程未完成,self就无法被释放
    let bannerView = GADBannerView(adSize: GADAdSizeBanner)
    self.bannerView = bannerView
    
    bannerView.delegate = self
    bannerView.rootViewController = self
    
    bannerView.load(GADRequest())
})

如果用户在授权弹窗弹出时,将当前ViewController(self)从导航栈移除或销毁,闭包仍会强持有self,导致ViewController无法被ARC回收,直到授权回调执行完毕——这会造成内存泄漏,严重时会积累大量无法释放的对象,影响App性能。

使用[weak self]的合理性

ATTrackingManager.requestTrackingAuthorization(completionHandler: { [weak self] status in
    guard let self = self else { return }
    
    let bannerView = GADBannerView(adSize: GADAdSizeBanner)
    self.bannerView = bannerView
    
    bannerView.delegate = self
    bannerView.rootViewController = self
    
    bannerView.load(GADRequest())
})
  • [weak self]让闭包对self的引用变为弱引用,不会阻止ARC回收self;
  • guard let self = self的「弱转强」操作,保证在后续代码执行时self一定存在,避免访问已释放对象的崩溃,同时不会形成循环引用(因为强引用只在闭包执行期间存在,执行完就释放)。

补充:其他类似场景的判断准则

对于系统API的异步回调(比如URLSession、CoreLocation的回调),只要满足以下任一条件,都应该用[weak self]:

  • 回调会被系统持有超过当前方法的执行周期;
  • self的生命周期可能比回调的持有周期短(比如ViewController可能在回调执行前被销毁);
  • 闭包内部需要访问self的属性或方法。

内容的提问来源于stack exchange,提问作者Cheok Yan Cheng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:33:10