block
Block:带有自动变量(局部变量)的匿名函数,它是C语言的扩充功能。之所以是拓展,是因为C语言不允许存在这样匿名函数。在Block中访问一个外部的局部变量,Block会持用它的临时状态,自动捕获变量值,外部局部变量的变化不会影响它的的状态,下面是个小例子。
int a = 10;
void (^block)(void) = ^{
NSLog(@"block = %d",a);
};
a = 5;
block();//结果为10
是否会对变量捕获遵循以下原则

block的本质
block本质上是一个OC对象,它内部也有个isa指针block是封装了函数调用以及函数调用环境的OC对象
block的类型

block类型的判断标准

block的copy
在ARC环境下,编译器会根据情况自动将栈上的
block拷贝到堆上,比如
1、block作为函数返回值时
2、将block赋值给__strong指针时
3、block作为cocoa API中方法名含有usingBlock的方法参数时
4、block作为GCD API的方法参数时
对象类型的auto变量
1、当
block内部访问了对象类型的auto变量时,如果block是在栈上,将不会对auto变量产生强引用
2、如果block被拷贝到堆上,会调用block内部的copy函数,copy函数内部会调用_Block_object_assign函数,_Block_object_assign会根据auto变量的修饰符(__strong,__weak,__unsafe_unretained)做出相应的操作,类似于retain(行程强应用、弱引用)
3、如果block从对上移除,会调用block内部的dispose函数,内部会调用_Block_object_dispose函数,这个函数会自动释放引用的auto变量,类似于release
__block修饰符
__block可以用于解决block内部无法修改auto变量值得问题
__block不能修改全局变量、静态变量(static)
编译器会将__block变量包装成一个对象
block产生的循环引用解决办法
用
__weak、__unsafe_unretained解决
用__block解决
__unsafe_unretained id weakSelf = self;
self.block = ^{
};
__block id weakSelf = self;
self.block = ^{
};
相信通过这片文章,大家对block有了一个全新的认识,希望有不足之处,大家可以指出,然后完善。