美文网首页
第三章:持有变量

第三章:持有变量

作者: userName | 来源:发表于2020-04-10 15:13 被阅读0次

    block主要准备分为3个文章记录。
    第一章:基础概念和使用
    第二章:捕获变量
    第三章:持有变量

    block可以在内存上存在以下3种形式,不同形式持有变量是不同的。我们先看下如果区分block是栈,堆,还是全局的。

    • _NSConcreteStackBlock,栈,生命周期由系统控制。函数返回后Block将无效;
    • _NSConcreteMallocBlock,堆,生命周期由程序员自己控制。
    • _NSConcreteGlobalBlock,全局,生命周期从创建到应用程序结束。

    一.blcok如何区分是在栈,堆,全局

    1._NSConcreteGlobalBlock全局
        __block int value = 20;
        int value1 = 10;
        int (^getBlock)(int num) = ^(int num) {
            //100 + 30 + 10
            return num + value + value1;
        };
        value = 30;
        value1 = 40;
        NSLog(@"getBlock-%d",getBlock(100));
    

    输出结果为:<NSGlobalBlock: 0x10207c798>
    没有用到外部变量或者只用了全局变量、静态变量的block都是_NSConcreteGlobalBlock。

    2._NSConcreteStackBlock栈

    栈上block的定义是:只用到外部局部变量、成员属性变量,且没有强指针引用的block都是StackBlock。
    但是在ARC下,很少存在栈上的block。因为很多情况下ARC会主动帮你把block copy一次。
    举个例子:

        __block int static_k = 3;
        void (^myBlock)(void) = ^{
            static_k++;
        };
        myBlock();
        NSLog(@"%@",myBlock);
    

    在MRC下,输出结果为__NSStackBlock栈。
    在ARC下,输出结果为__NSMallocBlock堆。
    因为在block在捕获外部变量时ARC会自动帮我们把栈上的block copy到堆上,其中还包括下面的情况系统也会主动copy一次。
    1.手动调用copy
    2.Block是函数的返回值
    3.Block被强引用,Block被赋值给__strong或者id类型
    4.调用系统API入参中含有usingBlcok的方法

    但并不是说在ARC上就没有栈上的block。其中当Block为函数参数的时候,就需要我们手动的copy一份到堆上了。其中GCD等系统方法中本身带usingBlock的方法,不需要处理。
    完整版本请看
    https://xiaozhuanlan.com/topic/4196075238

    相关文章

      网友评论

          本文标题:第三章:持有变量

          本文链接:https://www.haomeiwen.com/subject/waprmhtx.html