如果block只掌握了怎么去应用,那了解了block的皮毛。若想要精通block,非得了解block的本质不行!
<>block的实质
* block对象本质是一个结构体,里面主要信息有:isa指针指向自己的类(三类:global程序的数据区域、 malloc堆、
stack栈),desc结构体描述block的信息,__forwarding指向自己或堆上自己的地址。
* 如果block对象截获变量,这些变量也会出现在block结构体中。最重要的block结构体有一个函数指针,指向block代码块。
* block结构体的构造函数的参数,包括函数指针,描述block的结构体,自动截获的变量(全局变量不用截获)
* 引用到的__block变量。(__block对象也会转变成结构体)
*
block代码块在编译的时候会生成一个函数,函数第一个参数是前面说到的block对象结构体指针。执行block,相当于执行block里面__forwarding里面的函数指针。
<>__block做了什么?
总论:__block 所起到的作用就是只要观察到该变量被 block 所持有,就将“外部变量”在栈中的内存地址拷贝堆中。
分步来看:
__block int m = 0; struct __Block_byref_m_0 { void *__isa; __Block_byref_val_0
*forwarding; int __flags; int __size; int m; }; __Block_byref_m_0 *m;
以上是__block加上之后引起的变化,把原来的变量封装到了结构体里面。
由于此时的变量m变成了一个结构体指针变量,所以,在block里面对指针的操作,会影响指针指向的值的。所以,最终可以改变外部的值,这也是block的本质。
<>“_”(下划线)修饰的变量循环引用如何解决
{ NSMutableArray* _objects; } __weak typeof(self) weakSelf = self;
self.someBlock = ^{ __strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf->objects addObject:object]; };
原因是:_object在编译时被解释成 strongSelf->objects。
<>这些平时用的很少的变量block“冷”知识,你都了解多少呀?
热门工具 换一换