block应该注意的三个问题!
问题一: block对象的生命周期?
创新互联公司专业为企业提供开江网站建设、开江做网站、开江网站设计、开江网站制作等企业网站建设、网页设计与制作、开江企业网站模板建站服务,十多年开江做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
直接看代码,打印结果是什么?
#import//定义block对象(全局block) int (^externBlock)(void) = ^(void){return 100;}; //定义函数(block做为参数) void function(int (^block)(void)) { printf("执行block的结果是:%d\n\n", block()); } //定义的两个函数 void firstFunc(int number) { //定义块对象(局部) int (^blockWithinFirst)(void) = ^(void) { return number; }; //调用外部的function函数 function(blockWithinFirst); //赋值 externBlock = blockWithinFirst; } void secondFunc(int number) { //int局部变量 int index = 10; //block局部对象 int (^blockWithinSecond)(void) = ^(void) {return number * index;}; //调用外部function函数 function(blockWithinSecond); } int main(int argc, const char * argv[]) { @autoreleasepool { //1.调用function函数 function(externBlock); //2.调用firstFunc firstFunc(5); //3.调用secondFunc secondFunc(10); //4.和步骤1一样 function(externBlock); } return 0; }
问题二:Block体中访问全局变量/局部静态变量/局部变量的问题,如何解决(考察__block类型)
#importvoid function(int number, void (^blockParam)(void)) { //打印传入的number值 printf("传入的number是: %d\n", number); //调用传入的block对象 blockParam(); } int globalNumber = 1000;//全局变量(外部变量) int main(int argc, const char * argv[]) { @autoreleasepool { //块声明(没有传参,没有返回值) void (^internalBlock)(void); //局部静态变量 static int localStaticInt = 20; //局部变量:local variable(自由变量:free variable) int localInt = 20; //第一部分:将block对象最为函数的参数,在函数内部调用block //块定义(打印上面三个变量的值); internalBlock = ^(void) { printf("全局变量globalNumber:%d; 局部静态变量localStaticInt:%d; 局部变量localInt:%d\n", globalNumber, localStaticInt, localInt); }; //将internalBlock块对象作为function的参数,调用function函数 function(1, internalBlock); //第二部分:修改上述三个变量的值,重新调用function函数 globalNumber = 3000; localStaticInt = 0; localInt = 0; function(2, internalBlock); //第三部分:重新再写一次block的定义部分,再调用function函数 internalBlock = ^(void) { printf("全局变量globalNumber:%d; 局部静态变量localStaticInt:%d; 局部变量localInt:%d\n", globalNumber, localStaticInt, localInt); }; function(3, internalBlock); //第四部分:考察__block类型修饰问题 __block int localAnotherInt = 20; void (^firstBlock)(void) = ^(void) { globalNumber += 100; localStaticInt += 200; localAnotherInt = 10; printf("重新赋值后的globalNumber:%d;localStaticInt:%d; localAnotherInt:%d\n\n", globalNumber, localStaticInt,localAnotherInt); }; //调用/执行firstBlock firstBlock(); } return 0; }
分析:
初始化:全局:1000;局部静态:20;局部变量:20
a.function(1, internalBlock);包除了包含可执行的代码,还包含可访问的变量的值(全局:1000;局部静态:20;局部变量:20)
b.globalNumber =3000;
localStaticInt =0;
localInt =0;
function(2, internalBlock);
包除了包含可执行的代码,还包含可访问的变量的值(全局:3000;局部静态:0;局部变量:20);原因是block体内对局部变量没有修改的权限,还是原来第一次执行的包的数据
c.重新再定义internalBlock块对象,此时包内就重新包含了新的值(全局:1000;局部静态:0;局部变量:0)
internalBlock = ^(void) {printf("全局变量globalNumber:%d;局部静态变量localStaticInt:%d;局部变量localInt:%d\n",globalNumber, localStaticInt, localInt); };
function(3, internalBlock);
d.如果把局部的变量的类型添加__block类型,可以在block体中修改局部变量的值(重新赋值后的globalNumber:3100;localStaticInt:200; localAnotherInt:10)
问题三:Block体循环应用的问题,如何解决(考察__weak类型)
TRBlockObject *blockObj = [TRBlockObject new]; blockObj.block = ^void(void){ NSLog(@"blockObj%@“,blockObj); };
例子中,block属性是blockObj对象的;而在block体中,block又引用了blockObj对象,造成了循环引用。
解决的办法是:
TRBlockObject *blockObj = [TRBlockObject new]; //解决循环引用的方案使用__weak修饰符。 __weak TRBlockObject *weakBlockObj = blockObj; blockObj.block = ^void(void){ NSLog(@"blockObj%@",weakBlockObj); };
__weak是弱引用,blockObj被释放的时候,weakBlockObj已经是nil了。
文章名称:block应该注意的三个问题!
分享网址:http://scyanting.com/article/jcedjh.html