全局块、栈块、堆块

全局块、栈块、堆块

void (^block) ();
    int a;
    if (1 == a) {
        block = ^{
            NSLog(@"1");
        };
    } else {
        block = ^{
            NSLog(@"others");
        };
    }
    block();

定义在ifelse语句中的2block都会被分配到栈内存中。编译器会给每个block分配好栈内存,然而等离开相应的作用域后,编译器有可能会把分配给block的栈内存覆写掉。因此,上面的block只能保证其在ifelse语句作用域内有效,出了作用域有crash的可能。

解决办法:给块对象发送copy消息,如此就把块从栈拷贝到堆上了。拷贝后,块可以在定义的作用域外使用。一旦拷贝到堆上后,块就变成了带引用计数的对象了。后续的copy的操作都不会真的执行copy,只会增加块对象的引用计数。当块的对象的引用计数为0时,分配在块上的对象会像其他对象一样被系统回收。然而分配在栈内存的块,栈内存会被系统自动回收。所以以上代码是不安全的。使用copy之后,就不会出现crash问题了。

void (^testBlock) ();
    int b;
    if (1 == b) {
        testBlock = [^{
            NSLog(@"1");
        } copy];
    } else {
        testBlock = [^{
            NSLog(@"others");
        } copy];
    }

块可以分配在栈或堆上,也可以是全局的。分配在栈上的块可以拷贝到堆里,这样子,就可以和标准的OC对象一样,具有引用计数了!

查阅资料:Effective Objective-C 2.0  编写高质量iOS与OS X代码的52个有效方法

 

 

 

posted @ 2016-07-18 15:01 Kingdev 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值