关于Block的总结

为什么block会造成循环应用呢?

如果没有__weak修饰,block会把对象从栈copy到堆区,block结束的时候无法销毁。如果有__weak修饰,则只是copy了一个指针,block结束的时候就销毁了。



总结:Block的几种形式 分为全局Block(_NSConcreteGlobalBlock)、栈Block(_NSConcreteStackBlock)、堆Block(_NSConcreteMallocBlock)三种形式

  一.其中栈Block存储在栈(stack)区,堆Block存储在堆(heap)区,全局Block存储在已初始化数据(.data)区

二.如果对栈Block进行copy,将会copy到堆区,对堆Block进行copy,将会增加引用计数,对全局Block进行copy,因为是已经初始化的,所以什么也不做。


   1、不使用外部变量的block是全局block

    NSLog(@"%@",[^{

        NSLog(@"globalBlock");

    }class]);


    //输出 __NSGlobalBlock__


    //2、使用外部变量并且未进行copy操作的block是栈block

    NSIntegernum =10;

       NSLog(@"%@",[^{

           NSLog(@"stackBlock:%zd",num);

       }class]);

    //输出 __NSGlobalBlock__


    //日常开发常用于这种情况:

    [self testWithBlock:^{

        NSLog(@"----%ld",(long)num);

    }];


    //3、对栈block进行copy操作,就是堆block,而对全局block进行copy,仍是全局block

    NSIntegernums =10;

    void(^mallocBlock)(void) = ^{

            NSLog(@"stackBlock:%zd",nums);

        };

    NSLog(@"mallocBlock:%@",[mallocBlockclass]);

    __block typeof(self) weakSelf = self;


    _testBlock = ^{


        NSLog(@"%@",weakSelf);

    };


    _testBlock();


    //4.Block捕获变量  输出age:10,num:11

    autointage =10;

    staticintnumss =25;

    void(^Block)(void) = ^{

        NSLog(@"age:%d,num:%d",age,numss);

    };

    age =20;

    numss =11;

    Block();

}

- (void)testWithBlock:(dispatch_block_t)block {

    block();

    NSLog(@"===%@",[blockclass]);

}

推荐阅读更多精彩内容