Block存储域

第一、在OC中允许block改写值的变量有三种:

  1. 静态变量
  2. 全局变量
  3. 静态全局变量

code示例如下所示:

int global_val=1;

staticint static_global_val=2;

int main(int argc,const char * argv[]) {

   @autoreleasepool {


        static int static_val=3;

        void (^blk)(void)=^{

            global_val *=2;

           static_global_val+=3;

            static_val+=4;

           NSLog(@"global_val is %d",global_val);

           NSLog(@"static_global_val is %d",static_global_val);

            NSLog(@"static_val is %d",static_val);

        };

        blk();

        return 0;

    }

}

执行结果:

global_val is 2

static_global_val is 5

 static_val is 7

第二、Block存储域

__block说明符严格意义上来说是一种存储域说明符,用来指定该变量的存储位置

在C语言中,static表示存在静态变量区域,auto表示存储在栈中,register表示存在寄存器,__block变量是结构体类型的自动变量
Block是objective-c对象,_NSConcreteStackBlock表示存储为栈,_NSConcreteGlobalBlock表示全局变量区,

_NSConcreteMallocBlock表示存储区域是堆

1、_NSConcreteGlobalBlock实例

当block变量不适用截获的自动变量时,可以采用全局变量,如下所示
typedef void(^TEST)(void);
TEST test;
int main(int argc, const char * argv[]) {
    @autoreleasepool {
         int val=3;
        test=^{
            }
        test();
      return 0;
    }

}

2、_NSConcreteStackBlock栈类型block变量最常见
配置在全局变量的block,在变量作用域外通过指针可以安全地访问,但设置在栈上的block,如果其所属的变量作用域结束了,该block就被废弃,
复制到堆上的__block变量在变量作用域结束时不受影响
__block变量用结构体成员变量__forwarding可以实现无论__block变量配置在栈上还是配置在堆上都能够正确访问__block变量第四、
__block变量用结构体成员变量__forwarding实现无论__block变量无论在配置在栈还是配置在堆上,都能够正确访问__block变量
对于_NSConcreteStackBlock变量执行copy,会从栈复制到堆
对于_NSConcreteGlobalBlock变量执行copy,什么也不做
对于_NSConcreteMallocBlock变量执行copy,引用计数增加
copy示例:
blk=[[[[blk copy]copy]copy]copy];
解释为如下
{ /*
    *blk复制到堆
*将配置在堆上的block赋值给变量tmp
*变量tmp持有强引用的block
*/
blk_t tmp=[blk copy];
    /**
    * blk和tmp强引用block
    */
blk=tmp;
}
跳出作用域,tmp执行release释放,blk只有block没有被释放,以此循环。
结论:不管block配置在何处,用copy方法复制都不会引起任何问题,在不确定时用copy方法即可




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值