__weak && __block

本文详细解析了Objective-C中__weak与__block关键字的使用方式及区别。介绍了如何利用__weak避免循环引用问题,同时保持变量的有效性;并通过__block探讨了其作用域提升的特点与潜在风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

__weak

block内的 weakObj 和 block外的weakObj 不是同一个变量。

block捕获了weakObj,同时也对obj进行了弱引用。当在block外把obj释放之后,block内也读不到这个变量了。

当obj = nil时,block内的weakObj 也为nil 了。也就是说,obj实际上是被释放了。可见__weak是可以避免循环引用的问题的。

但是,在AFNetworking的源码中,会发现作者把变量在block外面先用__weak声明,在block内把前面weak声明的变量赋值给__strong修饰的变量。

这种写法的好处就是可以让变量在block内部安全可用,即使外部释放了,也会在blokc的生命周期内保留该变量。

这种写法既避免了循环引用的问题,又可以在block内部持有该变量。


__block

__block实际上是把变量的作用域给改变了。应该是提升了变量的作用域,使得blokc内部和外部所访问的是同一个变量。

类似于声明了一个static 和 globan变量的意思。

blockObj在地址在前后是有变化的,也就是说blockObj应该是block内部提升的作用域。

当外部的obj = nil 的时候,obj理应被释放,但实际上blockObj仍然强引用着obj,obj其实并没有真正被释放。因此使用_block并不能避免循环引用的问题。

但是我们可以通过手动去释放blockObj的方式来释放obj。这样就可以在block内部能够访问到obj,又可以避免循环引用的问题。但是这种方法不完美。

1、必须记住在block底部释放block变量,这其实和MRC有些类似了。

2、挡在block外部修改了blockObj的值的时候,block内部的值也会改变,反之在block内部修改blokcObj在外面使用时,值也会发生改变。这就可能会因为不小心从而带来安全隐患。

3、_blokc其实是提升了变量的作用域,在block内部访问的都是同一个blockObj可能会造成一些隐患。


总结:

__weak 本身是可以避免循环引用的问题的,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong 的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题

__block 本身无法避免循环引用的问题,但是我们可以通过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另外一点就是 __block 修饰的变量在 block 内外都是唯一的,要注意这个特性可能带来的隐患。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值