block
Block
:带有自动变量(局部变量)的匿名函数,它是C
语言的扩充功能。之所以是拓展,是因为C
语言不允许存在这样匿名函数。在Block
中访问一个外部的局部变量,Block
会持用它的临时状态,自动捕获变量值,外部局部变量的变化不会影响它的的状态,下面是个小例子。
int a = 10;
void (^block)(void) = ^{
NSLog(@"block = %d",a);
};
a = 5;
block();//结果为10
是否会对变量捕获遵循以下原则
block变量捕获
block的本质
block
本质上是一个OC
对象,它内部也有个isa
指针block
是封装了函数调用以及函数调用环境的OC
对象
block的类型
block的类型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
有了一个全新的认识,希望有不足之处,大家可以指出,然后完善。
网友评论