将self作为参数传入自身对象内部方法是否会产生retain cycle?
嘿,这个问题问到点子上了——很多刚接触内存管理的开发者都会在这个点上犯嘀咕。咱们分场景把这事说透:
Objective-C 场景下的情况
不管是 ARC 还是手动内存管理(MRC),单纯调用 self.someMethod(self) 本身都不会产生循环引用,核心原因是方法参数的引用是临时的:
- 在 ARC 环境中,方法参数默认是
__strong修饰,会临时持有self增加引用计数,但只要方法执行完毕,这个临时引用就会被销毁,引用计数随之回落。循环引用需要的是「双向长期强引用」,这里根本不满足条件。 - 在 MRC 环境中,除非方法内部显式调用了
[self retain]并长期持有,否则参数传递不会自动增加self的引用计数。只要方法执行完没留存这个引用,就不会有循环问题。
当然,如果你的 someMethod 里把传入的 self 存到了一个全局变量或者实例的强引用属性里(比如 self.anotherProperty = self),那这就会触发循环引用了——但这锅得归「长期存储」,不是传参数的行为本身。
Swift 场景下的情况
Swift 用 ARC 管理内存,函数参数默认是强引用,但同样只是函数执行期间的临时持有:
当你调用 self.someMethod(self) 时,someMethod 的参数会临时持有 self,但函数执行结束后,这个参数被销毁,引用计数就降回去了,完全不会形成循环引用。
只有一种例外:如果 someMethod 把传入的 self 存储到了一个长期存在的强引用属性里,比如下面这段代码:
class MyClass { var storedInstance: MyClass? func someMethod(_ obj: MyClass) { storedInstance = obj // 这里把self存成了强引用属性,形成循环 } func triggerMethod() { someMethod(self) } }
这种情况下才会出现循环引用,但本质还是因为「长期强引用」,不是传参数的操作导致的。
总结一下
单纯把 self 作为参数传入对象内部的方法,本身不会产生循环引用。循环引用的核心是「双向或自指向的长期强引用关系」,而方法调用时的参数只是临时持有,方法结束就释放,根本构不成循环的条件。
内容的提问来源于stack exchange,提问作者Tigran Iskandaryan
相关产品推荐
相关产品推荐

