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类型)

#import 
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了。


网页名称:block应该注意的三个问题!
文章链接:http://myzitong.com/article/jcedjh.html