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

Objective-C中弱引用传参及self弱转后传参的内存问题

Objective-C 弱引用传参与循环引用问题解答

让我来一步步拆解你的问题,这些都是Objective-C内存管理中很容易踩坑的点:

问题1:在Objective-C中,作为参数传递的引用是否仍保持弱引用特性?

答案是不会。弱引用的特性只绑定在你定义的那个变量上——它的作用是:这个变量本身不会增加对象的引用计数,当对象被销毁时,该变量会自动被置为nil。

但当你把这个弱引用变量作为参数传递给方法时,本质上传递的是它指向的对象的指针副本。方法的参数接收方拿到的只是一个指向对象的指针,这个指针本身没有“弱引用”的属性。接收方如果用强引用(比如赋值给strong修饰的属性)持有这个指针,就会给对象的引用计数+1,形成强引用;如果用弱引用持有,才会保持弱引用特性。

问题2:将self转成weakSelf再传参,是否能避免被强属性持有导致循环引用?

先看第一个小问题:提前转weakSelf和直接传self有没有区别?

有,但区别仅在于传参瞬间的安全性。比如如果在调用[self.someObject doWorkWithDelegate:]的那一刻,self刚好被销毁了,weakSelf会自动变成nil,传nil给方法不会有问题;但如果直接传self,此时self已经是野指针,可能会触发崩溃。不过这种极端场景并不常见,更多时候大家转weakSelf是习惯使然,或者是为了避免block中的循环引用,但在普通方法传参里,这个区别主要是防崩溃,不是防循环引用。

核心判断:你的结论是完全正确的!

即便你提前把self转成了weakSelf再传参,只要方法内部把这个参数赋值给了strong修饰的属性,依然会形成强引用,进而可能引发循环引用。

举个具体的代码例子帮你理解:

// 调用方代码
__weak __typeof(self) weakSelf = self;
[self.someObject doWorkWithDelegate:weakSelf];

// 被调用方的方法实现
- (void)doWorkWithDelegate:(Foo *)delegate {
    // fooDelegate是strong属性,赋值时会对delegate指向的对象retain一次
    self.fooDelegate = delegate;
}

这里的逻辑链是:

  1. weakSelf是指向self的弱引用,它本身不持有self;
  2. 传参时,方法拿到的是指向self对象的指针;
  3. 当把这个指针赋值给strong属性fooDelegate时,系统会自动给self的引用计数+1,相当于someObject强持有了self;
  4. 如果self本身也强持有someObject(比如self.someObject是strong属性),就会形成self → someObject → fooDelegate(指向self)的循环引用,双方都无法被自动释放。

总结一下:弱引用只是你这边的变量不持有对象,但接收方如果用强引用接住这个指针,就会建立新的强引用——这和你传参前是不是用weak修饰变量没有关系。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:25