前言
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就是后两者的结合。
内存拷贝
如果没有对weakBlock作copy处理,那么在设置为nil以后,在调用就找不到了,因为此时的strong和weak是同一片内存空间。
堆栈异常
第78行如果是__weak,相当于给外界的变量weakBlock赋值,此时还是在栈区,有了值以后,在调用的时候就没有问题,正常打印了1,0,但是如果改成__strong,此时就完成了对weakBlock值得拷贝,且此时的weakBlock是堆区的block,出了87以后,堆区的weakBlock销毁,会正常打印1,但是外界的weakBlock还是nil,在调用直接崩溃了。
循环引用
由于在快速退出时,weakSelf已经被销毁,所以在用它来指向这个name就是nil。
解决1 加__strong,延长了weakself的生命周期,在出了block代码块以后,strongSelf释放,weakSelf也就释放了。
解决2 给VC加一层捕获计数,防止它在vc消失的时候dealloc,再调用完成以后,手动置空。
解决3作为参数传入。
weakSelf未必修饰就可释放
被全局staticSelf_捕获,因为weakSelf和self指向的是同一片内存区域,所以正常来说是可以释放的,但是如果有其他变量捕获了,此时都在等待对方释放所以会造成循环引用。
由于内部进行doStudent对strongSelf又调一次block,又进行了捕获,此时计数从1到2,在出代码块的时候还是1,所以无法释放。