Block(上)

233 阅读2分钟

前言

block是在整个ios开发中,经常会用到的,话不多说,从无到有,特别是关于循环引用这一块的理解需要更加深入,希望能够从这篇笔记中把知识盲点整理清楚。

种类

全局block

在 block 内部不使用外部变量,或者只使用静态变量全局变量.

堆block

在 block 内部使用变量或者oc属性,并且赋值给强引用或者copy修饰的变量

栈block

与堆block一样,只不过不是赋值给强引用或者copy修饰的变量。

block面试题体验

指针计数

打印结果 :1 3 4 5 。

创建 1 ,捕获+1,但是strong会copy一份+1,weak不会copy但是捕获正常+1,copy正常+1,strong就是后两者的结合。 截屏2021-08-23 下午4.39.38.png

内存拷贝

如果没有对weakBlock作copy处理,那么在设置为nil以后,在调用就找不到了,因为此时的strong和weak是同一片内存空间。 截屏2021-08-23 下午4.42.00.png

堆栈异常

第78行如果是__weak,相当于给外界的变量weakBlock赋值,此时还是在栈区,有了值以后,在调用的时候就没有问题,正常打印了1,0,但是如果改成__strong,此时就完成了对weakBlock值得拷贝,且此时的weakBlock是堆区的block,出了87以后,堆区的weakBlock销毁,会正常打印1,但是外界的weakBlock还是nil,在调用直接崩溃了。

截屏2021-08-23 下午4.49.42.png

循环引用

由于在快速退出时,weakSelf已经被销毁,所以在用它来指向这个name就是nil。 截屏2021-08-23 下午5.20.08.png

解决1 加__strong,延长了weakself的生命周期,在出了block代码块以后,strongSelf释放,weakSelf也就释放了。

解决2 给VC加一层捕获计数,防止它在vc消失的时候dealloc,再调用完成以后,手动置空。

截屏2021-08-23 下午5.33.06.png

解决3作为参数传入。

截屏2021-08-23 下午5.37.32.png

weakSelf未必修饰就可释放

被全局staticSelf_捕获,因为weakSelf和self指向的是同一片内存区域,所以正常来说是可以释放的,但是如果有其他变量捕获了,此时都在等待对方释放所以会造成循环引用。 截屏2021-08-23 下午5.49.29.png

由于内部进行doStudent对strongSelf又调一次block,又进行了捕获,此时计数从1到2,在出代码块的时候还是1,所以无法释放。 截屏2021-08-23 下午6.01.39.png