block基础知识

1.什么是block? block和函数指针很象,
函数指针的声明方法为:返回值类型 ( * 指针变量名) ([形参列表]); int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ 此函数指针指向的函数返回值为一个int类型,参数为一个int类型, f=func; /* 将func函数的首地址赋给指针f */ block的原型 int ( ^ f )( int ); 指向一个返回值为int类型,参数为int类型的block。 和函数指针的唯一区别就是^替代了*。 f = ^(int val){ return val * 2; }; int a = f(5); 可以得到a值为10. blocks是封装了一段代码,可以在任何时候执行,可以当作参数或者返回值,但是和函数指针也有不同的地方:blocks是inline的,并且对于局部变量是只读的,blocks在oc中是一个对象。
block和函数指针的不同地方,其一是block为对象,其二为block可以访问函数外作用域的变量的值。
2.block的几种类型 2.1:NSGlobalBlock
全局的静态block,当block定义在函数体外面,或者定义在函数体内部且当时函数执行的时候,block体中并没有需要使用函数内部的局部变量时,也就是block在函数执行的时候只是静静地待在一边定义了一下而不使用函数体的内容,那么block将会被编译器存储为全局block。例如: 定义在函数外: int (^tBlock)(int) = ^(int val){return val *2;}; int main(int argc, char * argv[]) {     NSLog(@"tBlock:%@",tBlock); } 2016-01-14 17:45:25.863 BlockTest[33440:8235986] tBlock:<__NSGlobalBlock__: 0xed120>

定义在函数内,但没有用函数内的变量: int main(int argc, char * argv[]) {     int (^tBlock)(int) = ^(int val){return val *2;};     NSLog(@"tBlock:%@",tBlock); } 2016-01-14 17:47:06.195 BlockTest[33504:8238173] tBlock:<__NSGlobalBlock__: 0x102128> 定义在函数内,使用了静态变量: int main(int argc, char * argv[]) {     static int a = 2;     int (^tBlock)(int) = ^(int val){return val *a;};     NSLog(@"tBlock:%@",tBlock); } 2016-01-14 17:48:44.210 BlockTest[33562:8239939] tBlock:<__NSGlobalBlock__: 0x52128> ps:此处是表态变量定义在函数内,定义在函数外,也依然相同
2.2:NSStackBlock
对于MRC,保存在栈中的block,当函数返回时被销毁。例如: int main(int argc, char * argv[]) {     int a = 2;     int (^tBlock)(int) = ^(int val){return val *a;};     NSLog(@"tBlock:%@",tBlock); } 2016-01-14 18:00:54.704 BlockTest[33815:8249200] tBlock:<__NSStackBlock__: 0xbff8e700>
2.3:NSMallocBlock
堆block,对于ARC下,只要不是全局block,函数内的block也都会被copy到堆上,成为NSMallocBlock int main(int argc, char * argv[]) {     int a = 2;     int (^tBlock)(int) = ^(int val){return val *a;};     NSLog(@"tBlock:%@",tBlock); } 2016-01-14 18:02:26.051 BlockTest[33865:8250555] tBlock:<__NSMallocBlock__: 0x790069b0> 对于MRC,只有对NSStackBlock copy的block才是NSMallocBlock的。

3.block内存管理 block在oc中其实是对象,但是和一般的NSObject管理内存的方式有些不同

Block的copy、retain、release操作

对于NSStackBlock和NSMallocBlock retain和release都不起作用
对于MRC环境:
需要显式的执行copy和release方法。
对于ARC环境:
大部分情况下编译器已经为我们做好了,会自动将block从栈复制到堆上。包括以下几种情况:
1.在block作为返回值时
类似在非ARC的时候,对返回值block需要执行[[returnBlocd copy] autorelease];
2.方法的参数中传递block时
3.Cocoa框架中方法名中还有useringBlock等时
4.GCD相关的一系列API传递block时。
如:
[mutableArray addObject:stakBlock];在MRC下如果使用此block的话,就会崩,但在ARC环境下系统会先copy再add到mutableArray里。
NSMallocBlock支持retain、release,虽然retainCount始终是1,但内存管理器中仍然会增加、减少计数。copy之后不会生成新的对象,只是增加了一次引用,类似retain;此处没有太理解,有理解的请指教


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值