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

为何Weak-Strong Dance会引发循环引用?附代码及日志

你的Weak-Strong Dance用法没问题,根本不会导致循环引用!

先给你明确结论:你这段代码没有产生循环引用,Weak-Strong Dance本身就是iOS开发里用来避免循环引用的标准手段,你的写法完全正确。咱们慢慢拆解:

先搞懂循环引用的本质

循环引用必须形成一个「强引用闭环」:比如 self 强持有 block(你的 blk 属性如果是默认的 strong 修饰,就属于这种情况),同时 block 也强持有 self,这样两者互相攥着对方,谁都没法被系统回收,才会造成内存泄漏。

你的代码里的引用逻辑

  1. 你写的 __weak typeof(self) weakSelf = self; —— 这里的 weakSelf 是对 self 的弱引用,不会增加对象的引用计数,也不会阻止 self 被释放,相当于给 self 留了个“观察位”,但不攥着它。
  2. block 内部的 __strong typeof(weakSelf) strongSelf = weakSelf; —— 这一步是在 block 执行的这段时间里,临时给 self 加个强引用,防止执行到一半 self 突然被释放(比如异步操作场景下很有用)。但注意,strongSelf 是 block 内部的局部变量,block 一执行完,这个强引用就立刻消失了。
  3. 你直接调用了 self.blk(); —— block 被立即执行,执行完之后,如果没有其他地方再持有这个 block,self 对它的强引用也会跟着解除,整个引用链就断得干干净净。

所以从头到尾,根本没形成持续的强引用闭环,自然不会有循环引用的问题。

关于日志里的相同地址

你看到三个日志的内存地址完全一致,这太正常了:

  • weakSelf 只是 self 的弱引用指针,指向的是同一个对象实例,地址当然和 self 一样;
  • strongSelf 是通过 weakSelf 强引用过来的,本质还是指向同一个对象,地址自然也相同。这跟循环引用一点关系都没有,只是说明它们都指着同一个对象罢了。

什么时候Weak-Strong Dance会“踩坑”?

只有当 block 被长期持有的时候(比如作为重复触发的定时器回调、或者被一个和 self 生命周期绑定的对象持有),同时你在写法上犯了错(比如把 strongSelf 声明在 block 外面,或者在 block 里把 strongSelf 赋值给了 self 持有的另一个属性),才可能意外造成循环引用。但你的代码里完全没有这些情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:11:48