推广

关于block的循环引用,你看我就够了!

iseeyu2年前 (2024-02-22)推广109

循环引用代码实例

以上造成循环引用的原因是myBlock持有了person对象,而person内部也持有了myBlock,导致循环引用

person -> myBlock ->person

用图来解释就是:

self和block相互持有,类似上面一摸一样

解释:当person要释放的时候,因为里面持有myBlock,所以无法释放自己;同时myBlock也会等着person释放自己,所以形成了相互持有都无法释放

我在GDPerson里面调用dealloc方法,并在里面打印打印 NSLog(@”%s”,__func__);我们看下会不会调用很明显程序执行完毕也不会调用这个dealloc方法,接下来我们看看解决方案

解决循环引用的题-ARC

解决block的循环引用,我们一共可以用3种方案来解决,首先我们来看ARC模式下有哪些方案

1.用_ _weak解决

首先我们知道现在是person ->block 和 block -> person,我们只要其中一个强引用变没有,就解决了这个问题了吧,一般我们更希望block -> person这个条线断开,因为person是一个对象里面存着block,我们希望保留那条关系,如下请看如下代码:

ARC环境下运行

这个是不是就解决了这个问题,好我们clang一下,把main.m转成c++看一下(命令:xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m -o main.cpp)

ARC环境下运行

如果你看过我之前的博客,你应该非常清楚这段源码:栈block进行copy操作成堆block的时候,调用对象的时候会自动生成如上的copy和dispose函数,然后copy函数又会调用内部__main_block_copy_0函数,然后再调用_Block_object_assign函数,会根据你上面传入的是weak还是strong对这个是这个对象是否持有的操作.明显传入的weak,所以不会持有(细节可以参考之前的博客,这知识说一下大致内容)

2.用_ _unsafe_unretained解决

首先我们来说下,__unsafe_unretained和__weak的区别:

__unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址不变

__weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil

__unsafe_unretained直面翻译也是不安全的,主要是对象销毁了,释放了,再去访问它,就可能变成野指针,所以不安全,而__weak再访问它,顶多是nil,不会报错!__unsafe_unretained这个非常少用,如果是面试的时候还是可以答一下,它确实能解决循环引用

好,我们看一下下面的代码结果:

ARC环境下

一看,确实调用了dealloc方法,也确实确定解决了循环引用

3.用_ _block解决

首先我们知道_ _block能用解决block内部想修改外部的auto的问题,它其实也能解决循环引用的问题,如果面试官问你_ _block有什么用,我想你肯定能答对这2个作用,好吧,话不多说,我们继续,先看结果,再解释原因

ARC环境下

这里看看,是不是也是调用了dealloc方法,说明是成功的释放了,解决了循环引用,但是有个弊端就是,你必须要调用上面的我圈出来的红色的代码,才能解决循环引用 MyPerson =nil; person.myBlock();这两句.

那我们就来看一下是什么原因,首先我们先看这个为什么会有循环引用,我们先来回顾一下之前的知识,加了__block会生成什么,请看下图

ARC环境下

所以__block就会持有person,这个之前的博客都是介绍的很清楚,所以,代码中的block就有三个

这张图很清晰解释关系

person->block;   block->__block; __block->person

正好是三角循环,所以更是造成了循环引用.所以我们只要把其中强引用去掉就行了,所以我把对象置为nil就是把__block->指向对象的那条线,那个强引用删除了啊,对象不存在,自然关系也不存在,也是解决了循环引用的问题.

这个唯一的弊端就是你要写那2句代码,如果你只写了block内部置为nil的代码,而不去调用它,那也会造成内存泄漏!

解决循环引用的问题-MRC

这个知识点作为了解,因为现在都是ARC,万一面试官问你ARC的情况,你也要了解,

因为MRC没有__weak的理念,我们就不讨论这个了,不支持弱指针

1.用_ _unsafe_unretained-解决

大家先看下面的代码结果。  (注意改成MRC测试哦!)  而且MRC要调用[super dealloc];

MRC环境运行

所以很明显,这个是可以解决MRC环境下的循环引用的问题.

2.用_ _block-解决

首先我们还是先看结果

MRC环境运行

这个就是一个区别,一个不一样的地方,在MRC情况下,不管你myPerson是强指针还是弱指针,__block都不会对person进行强引用,这就是区别.

总结:

这里我们就能总结之前的block的面试题了,请看下(几篇博客的一起总结结果)

下面只是大致写了一下,供大家参考,很多我之前都总结了,我就没有每个都搬运过来.

1.block的原理是怎么样的?本质是什么?

block本质是一个oc对象,它内部也有个isa指针,block内部封了函数调用及函数调用的oc对象.

2._block的作用是什么?有什么使用注意点?

可以在block内部修改auto变量,还可以解决循环引用,注意内存地址的处理,而且在MRC环境下__block不会对对象产生强引用

3.block的修饰词为什么是copy?使用block有哪些使用注意?

复制到堆上,存活时间更长久,更好的使用它,注意循环引用等.

4.block在修改NSMutableArray,需不需要添加_block?

不需要,因为是使用它,不是修改它,能不用_block就不要用_block,因为会生成更多东西.

接下来博客我会介绍Runtime的知识点,来探讨Runtime

如果觉得我写得对您有所帮助,请关注我,我会持续更新?

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/55835.html

相关文章

淘宝卖护肤品怎么办授权(淘宝商品授权怎么弄)

淘宝卖护肤品怎么办授权(淘宝商品授权怎么弄)

如果是正规的品牌要看他们的规定,如果没有说不能在网络销售,那么不需要授权。如果有规定,那么要向他们公司申请授权书,即使淘宝不查你,公司知道了也会投诉你的。...

网页优化SEO内容如何布局。

网页优化SEO内容如何布局。

笔者以电子商务网站为例进行剖析,论述了网站内容布局等建造性主张。一个好的电子商务网站需求供给会员注册消费信息产品查找产品功用和谈论等信息,才能从用户的视点精心布局网站。简化客户的订单请求承认和付款流程。 在网站栏目屡次更新的情况下,需求组成一个团队来填充内容。内容是网站的魂灵,许多...

小编分享那么什么样的网站结构比较好呢。

小编分享那么什么样的网站结构比较好呢。

那么什么样的比较好呢? 网站结构和页面结构对于网站SEO优化来说都是很重要的,当然这没有绝对的标准,百度搜索也没有给出具体的指标来说明什么样的网站结构更加适合用户。那么什么样的网站结构比较好呢,我们不妨从搜索引擎和用户体验两个角度来分析。 那么什么样的网站结构比较好呢? 一、从搜索引擎的角度来...

【营销与销售】工业品营销渠道02

【营销与销售】工业品营销渠道02

模式的价值与风险一、工业品渠道模式的价值:1、疏通制造商与最终用户之间的阻碍。2、信息收集。3、减轻财务压力。4、提高交易效率,降低交易成本。5、最大地接近最终用户。6、共享渠道资源。7、规避直销风险。二、工业品渠道模式的风险:1、制造商对渠道商缺乏足够的控制力。2、渠道商...

「乐事x泡泡玛特」营销策略分析 day3

「乐事x泡泡玛特」营销策略分析 day3

一说到限定联名,多数只想着在包装和概念上下功夫今天就带你看个不一样的身处粉色樱花海洋它是怎么脱颖而出的,而乐事借助泡泡玛特潮玩IP的限定玩法则是既要做到“春日限定",也要“细水长流”。1.限定产品3款联名薯片主打高端健康时令食材,给予大众平价吃“高端”的新奇感在包装上,用三...

微信月活已达12亿,你该怎么做私域流量社群运营?

微信月活已达12亿,你该怎么做私域流量社群运营?

2021年布局私域社群、企业微信的大企业越来越多,包括宝岛眼镜、波司登、欧莱雅等很多企业都把社群、企业微信作为自己的标准配置。 有很多想开始做私域社群运营的人都不知道自己到底是该怎么运作好自己的社群体系。 很多人在做社群之前都会问我,老师,我要搭建社群体系,我该怎么做? 这时候其实他...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片