Block概念:
将函数及其执行上下文封装起来的对象,Block与函数类似,只不过是定义在另一个函数里,和定义它的函数共享统一范围的数据。
与C语言不同之处
1、没有函数名,因为是匿名函数
2、带有“^”符号,插入该符号便于查找
Block语法
1、^ 返回值类型 参数类型 表达式
例如 : ^int (int count){return count + 1;}
2、^ 参数类型 表达式
void类型,无返回值
^void (void) { NSlog(@"无返回");}
有返回值,需要return
^(int count) {return count + 1;}
3、^ 表达式
^{ NSlog(@"无返回");}
Block类型变量
声明一个Block,既指源代码中的Block语法,也指由Block语法所生成的值
int (^blk)(int)
Block的分类:
NSGlobalBlock是全局Block
它位于程序的.data区内,copy操作时,全局Block什么都不做;它不会被系统回收,某种程度上类似于单例;
NSStackBlock是栈Block
它位于栈区,超过变量作用域,Block和__block变量都会被销毁;
copy操作时,会将栈区的Block复制到堆上一份,栈区Block的__forwarding指针也会指向堆区新生成的Block;
NSMallocBlock是堆Block
它位于堆区,变量作用域结束时并不会收到影响;
堆区的 Block无法直接创建,主要是栈区的Block经过执行copy操作后放入堆中;
堆中的Block调用copy操作后,堆Block就是带了引用计数的对象,后续的复制操作都不再会执行复制操作,而是将Block的引用计数递增;
在ARC环境下,Block会被系统自动释放,MRC环境下,需要手动调用release来管理引用计数,引用计数为0后,就会被系统回收;
Block关于变量与传递
基本数据类型的局部变量,值传递,外界变量值改变,内部不会受影响;
对象类型的局部变量,指针传递,会将对象的所有权修饰符一起传递;
局部静态变量:指针传递
全局变量、静态全局变量:指针传递
值传递:外界值变化,不会影响Block内部;
指针传递:Block内的变量与外界属于同一变量,外界改变,里面也会做出相应变动;
可以通过Clang将main.m中的文件编译为C++文件,网上都写的在终端输入命令clang -rewrite-objc main.m,这个clang语句会报无法查找错误

正确语句 xcrun -sdk iphonesimulator clang -rewrite-objc main.m

Block常用关键字与循环引用问题
__weak、__block、__strong、__forwarding
__block
一般情况下,对非静态局部变量进行赋值操作需要使用__block做修饰
对于静态局部变量、全部变量、静态全局变量赋值时一般不需要进行赋值
__forwarding
不管在任何内存位置,都保证Block可以访问到同一个__block变量
循环引用:
MRC 情况下,使用__block可以消除循环引用
ARC情况下,使用__weak弱引用才可以消除引用循环;
但使用__weak,你不能确定什么时候self将会被释放,为了保证某些延时操作时,block无法取到self,在block内部需要使用__strong将弱指针进行强引用
网友评论