首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Blocks笔记(3)

Blocks笔记(3)

block的存储域

根据Block在内存中的位置分为三种类型_NSConcreteGlobalBlock,_NSConcreteStackBlock, _NSConcreteMallocBlock。

    _NSConcreteGlobalBlock:类似函数,位于text段;
    _NSConcreteStackBlock:位于栈内存,作用域结束后后Block将无效;
    _NSConcreteMallocBlock:位于堆内存。

    1、当 block 写在全局作用域时,即为 global block;
    2、当 block 表达式不引用任何外部变量时,即为 global block;

在以上两种情况下生成的block为_NSConcreteGlobalBlock,其余均为_NSConcreteStackBlock,当 block 从栈拷贝到堆后,当栈上变量作用域结束时,仍然可以继续使用 block,因为此时的block位于堆上,block的类型为:_NSConcreteMallocBlock;所以会将 _NSConcreteMallocBlock 写入 isa如:

impl.isa = &_NSConcreteMallocBlock;

    栈上的block:

    pragma mark - 栈上的block
     -(IBAction)test_2id)sender {
        NSArray *array = [self getBlockArrayFromStack];
        //    [self test];
        void(^block)(void);
        block = array[2];
        block();
    }
     
     -(void)test {
        NSLog(@"hello world!");
    }
     
      - (NSArray *)getBlockArrayFromStack {
        NSArray *blockArray = [[NSArray alloc]initWithObjects:  ^{NSLog(@"block-1");},
                                                                ^{NSLog(@"block-2");},
                                                                ^{NSLog(@"block-3");},nil];
        return blockArray;
    }

上面代码中注释的[self test]看似对程序无影响,但是打开注释就会导致程序崩溃,关闭则无能正确执行;原因在于:一个方法调用的栈帧没有被新的数据覆盖,仍然保留原来block数据的原因所致。这样显然是不安全的,是不能保证block数据可用的。
返回列表