Block概述
Block它是C语言级别和运行时方面的一个特征。Block封装了一段代码逻辑,也用{}括起,和标准C语言中的函数/函数指针很相似,此外就是blokc能够对定义环境中的变量可以引用到。这一点和其它各种语言中所说的“闭包”是非常类似的概念。在iOS中,block有很多应用场景,比如对代码封装作为参数传递。这在使用dispatch并发(Operation中也有BlockOperation)和completion异步回调等处都广泛应用。
Block是苹果官方特别推荐使用的数据类型,使用场景比较广泛 动画 多线程 集合遍历 网络请求回调 Block的作用 用来保存某一段代码,可以在恰当时候再去出来调用 功能类似于函数和方法block对变量的捕获
1:可以捕获不可以修改变量
局部变量2:可以捕获且可以修改变量
全局变量 静态变量 __block修饰的局部变量原理分析:
1. 局部变量为什么可以被捕获确不能修改
int a = 10;
void (^blcok)() = [^{
NSLog(@"%d",a);
} copy];
a=20;
blcok(); // log : a = 10
结果应该大家都知道,但是为什么会这样呢?
我们用clang转化之后看看

从block定义来看
void (*blcok)() = (void (*)())((id (*)(id, SEL))(void *)objc_msgSend)((id)((void (*)())&__ZMX__blockTest_block_impl_0((void *)__ZMX__blockTest_block_func_0, &__ZMX__blockTest_block_desc_0_DATA, a)), sel_registerName("copy"));
block的实现是通过__ZMX__blockTest_block_impl_0结构体的构造方法来定义的,我们来看下这个结构体
struct __ZMX__blockTest_block_impl_0 {
struct __block_impl impl;
struct __ZMX__blockTest_block_desc_0* Desc;
int a;
__ZMX__blockTest_block_impl_0(void *fp, struct __ZMX__blockTest_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
impt:
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
isa:指向Class的指针
flags:一些标识
reserced:保留的一些变量
funcptr:函数指针
__ZMX__blockTest_block_desc_0:
static struct __ZMX__blockTest_block_desc_0 {
size_t reserved;
size_t Block_size;
} __ZMX__blockTest_block_desc_0_DATA = { 0, sizeof(struct __ZMX__blockTest_block_impl_0)};
reserced:保留的一些变量
size:内存大小
__ZMX__blockTest_block_impl_0 构造方法
我们可以看到这个构造方法有四个参数










