推广

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

iseeyu3年前 (2024-02-22)推广121

循环引用代码实例

以上造成循环引用的原因是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

相关文章

西安企业做百度推广,一个月花三千和花三万到底差在哪?

4|最近跟几个西安的老板聊天,发现一个挺有意思的现象:同样做百度推广,有人一个月花三千块,询盘不断;有人一个月砸三万,水花都没见着。问他们区别在哪,大多数人说不清楚,只知道'钱花了,没效果'。 5| 6|百度推广这东西,说复杂也复杂,说简单也简单。核心就一件事:让你的潜在客户搜某个词的时候,你的信息...

我想当策划,大学应该选什么专业?

我想当策划,大学应该选什么专业?

学,广告,传播,公关,这些专业其实都可以。另外也可以学像汉语言文学,以及一些跟文学相关的一些专业,会对你找工作有帮助。但是,你想从事这个这份职业,除了专业的学习之外,更多的是,你要在上学的时候积极参与一些更营销策划相关的社会实践。比如说你可以做一些兼职,比如说帮别人去写稿,...

服装市场营销策略分析,“定位不慎满盘皆输”

服装市场营销策略分析,“定位不慎满盘皆输”

不同的区域需要不同的策略,而不同的营销策略需要不同的销售思路来配合。因此,在研究女装产品销售思路之前,最好先对于市场与营销策略做一次深入地了解。1.市场区域化(market segmentation):目标营销的第一步,是将整个市场拆分成若干个同性质的小市场。2.目标市场的...

晚间悦读丨你的思维方式,决定你的人生高度!

晚间悦读丨你的思维方式,决定你的人生高度!

越长大,越发现,能够决定你人生高度的,往往是你的认知层次。 你的认知在哪个层级,你的人生就处在什么状态。你认知的高度,决定了你人生的高度。 那如何才能升级方式、提升认知能力呢?可以从这三个方面做出改变。 NO. 1 改变态度 有人...

编写项目营销策划方案六大要点

编写项目营销策划方案六大要点

现在商业发展非常迅速,的需求非常的大,但是要做好营销策划是有一定难度的,我把自己做营销策划的一些体会在这里分享给朋友们。营销策划方案六大要点我们先说项目营销策划方案这个话题。大部分的营销策划人都是在企业里工作,大部分项目之初都是来源于一个想法,创始人、老板或者创始团队的一个...

【商场营销策划】如何进行商场营销策划?

【商场营销策划】如何进行商场营销策划?

商场是策划者们关注的永恒话题,那么究竟该如何作好商场营销策划呢?掌握以下这几点营销策略设计原则,至关重要!1.义利兼顾的原则。商场在获取利润的同时要充分考虑到消费者的合法利益和商场的长远利益。在作商场活动营销策略方案的时候应该将这一点作为首要的原则。对商场有利而对顾客不利的...

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

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