在Block中使用包裹函数的局部变量时,是否需进行weakify处理?
关于闭包中局部变量的Weakify处理疑问
嘿,这个问题抓得很准!先直接给你结论:完全不需要对这类函数内定义的局部变量做weakify处理,下面我给你拆解清楚背后的逻辑:
为什么局部变量不用weak处理?
循环引用的本质是两个对象互相持有强引用,形成ARC无法打破的引用环。而你函数里的局部变量(比如示例中的someVariable),它的生命周期本来就和当前函数的调用栈绑定:函数执行完之后,只要没有其他强引用攥着它,ARC会自动把它回收掉。
当你把这个局部变量放进闭包里时,闭包确实会对它产生一个强引用,但这里根本不会形成循环引用——原因很简单:
- 局部变量本身不会持有这个闭包的引用(除非你主动把闭包赋值给了这个变量的某个属性,但一般局部变量不会这么设计)
- 闭包只是被
someOtherFunction持有,而someOtherFunction的生命周期和你的局部变量没有互相绑定的关系
给你补全示例代码,这样更直观:
func someFunction(){ let someVariable = MyObject() someOtherFunction(completionBlock:{ [weak self] in print(someVariable.name) // 直接用,完全没问题 self?.doStuff() }) }
什么时候才需要处理局部变量的引用?
只有当局部变量和闭包之间形成了互相持有的引用环时,才需要考虑weak处理。举个典型的反例:
func someFunction(){ let someVariable = MyObject() // 假设MyObject有一个闭包类型的属性 someVariable.storedClosure = { [weak self] in print(someVariable.name) // 这里就炸了!someVariable持有闭包,闭包又持有someVariable,形成引用环 self?.doStuff() } }
这种情况下,你才需要把someVariable也加入weak列表,改成[weak self, weak someVariable],打破这个引用环。
一句话总结
- 普通函数内的局部变量,在闭包里直接用就行,不用额外weak处理
- 只有当局部变量和闭包互相持有强引用时,才需要对局部变量做weakify
内容的提问来源于stack exchange,提问作者Sti
相关产品推荐
相关产品推荐

