温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

block应该注意的三个问题!

发布时间:2020-07-09 15:06:45 来源:网络 阅读:483 作者:禅信23 栏目:移动开发

问题一: block对象的生命周期?

直接看代码,打印结果是什么?

#import <Foundation/Foundation.h> //定义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类型)

#import <Foundation/Foundation.h> void 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了。


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI