谈谈你对block的理解
1、本质、原理:block俗称代码块,本质上也是一个对象。它将代码块中需要执行的代码封装成一个函数,并且在自己的结构体内,存有这个函数地址,当需要执行block的时候,就通过这个函数地址,找到需要执行的函数并执行。
2、block的类型分为三种:
globalBlock:存放在数据区域:没有访问auto变量
stackBlock:存放在栈:访问了auto变量
mallocBlock:存放在堆:stackBlock 调用了copy
block循环引用问题:
如果block被拷贝到堆上。会调用block内部的copy函数。copy函数会再调用到_Block_object_assign函数,_Block_object_assign会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)做出对应的引用方式,是强引用还是弱引用,就是在这个环节出现的。
比如viewcontroller持有了一个block,并执行这个block,并在block内部使用self。 self对block有强引用。 block通过变量捕获,将self捕获到block内部,在block执行copy时,又对self做了一个强引用。这样就出现循环引用了。解决方式在上面也有说明,就是把self 通过__weak来修饰。
__block 做了什么事情?为什么通过__block 修饰的变量,被捕获之后,就可以修改它的值了?
比如,有个变量int age. 希望在block内部访问并修改它的值。 __block 修饰age,在age被捕获到block内部时,实际上是动态创建了另一个对象age0,age0内部有一个属性是int age。然后block捕获进来的是一个对象age0,也就是一个指针,既然是指针,那么我就可以找到age0的地址,并访问age0内部的age,当然也可以修改它了。
如果没有__block修饰的话,在age被捕获到block内部时,仅仅只是值传递,所以无法修改原age的值。