美文网首页
浅谈block(三)三种类型的block

浅谈block(三)三种类型的block

作者: frola_ | 来源:发表于2018-12-25 09:53 被阅读0次

Block存储域

在 Objective-C 语言中,一共有 3 种类型的 block

Block的类

设置对象的存储域
_NSConcreteStackBlock
_NSConcreteGlobalBlock 程序的数据区域 (.data区)
_NSConcreteMallocBlock

三种block在内存中的对应位置如图所示


image.png

前两章所说到的block都是属于_NSConcreteStackBlock类型的,并且设置在栈上的,并非全是如此。

block类型的区分

1、_NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。

以下情况,block为_NSConcreteGlobalBlock类型
  • block内部只使用了全局变量
  • block内部没有使用任何外部的局部变量

除了以上两种情况,其他的block为_NSConcreteStackBlock类型。
而对于_NSConcreteMallocBlock,只有当_NSConcreteStackBlock类型的block执行copy操作(手动或者系统执行)时,该block才会是_NSConcreteMallocBlock类型

1、_NSConcreteGlobalBlock

void (^blk)(void)  = ^(printf("Global Block \n"););
int main (){
}

上面的代码通过调用全局变量blk来使用block语法,如果转化成源代码,从block结构体的成员变量isa就可以看出 ,isa指向_NSConcreteGlobalBlock

struct __globalBlock_block_impl_0 {
  struct __block_impl impl;
  struct __globalBlock_block_desc_0* Desc;
  __globalBlock_block_impl_0(void *fp, struct __globalBlock_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteGlobalBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

Block的类为_NSConcreteGlobalBlock类,即该block用结构体实例设置在程序的数据区域中。因为使用全局变量的地方不能使用局部变量,所以不存在对变量的截取,在整个使用过程中,结构实体的内容不依赖执行时状态,Block用结构体每次截获的值都完全相同,因为只有一个实例,所以Block用结构体实例设置在与全局变量相同的区域就可以了。'
2、_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。sa 指向 _NSConcreteStackBlock,说明这是一个分配在栈上的实例。

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int age;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags=0) : age(_age) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

我们可以看出,

  • isa 指向 _NSConcreteStackBlock,说明这是一个分配在栈上的实例。
  • __main_block_impl_0 中增加了一个变量 age,在 block 中引用的变量 age实际是在申明 block 时,被复制到 __main_block_impl_0 结构体中的那个变量 a。因为这样,我们就能理解,在 block 内部修改变量 a 的内容,不会影响外部的实际变量 age。
  • __main_block_impl_0 中由于增加了一个变量 age,所以结构体的大小变大了,该结构体大小被写在了 __main_block_impl_0 中。

3、_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。
NSConcreteMallocBlock 类型的 block 通常不会在源码中直接出现,因为默认它是当一个 block 被 copy 的时候,才会将这个 block 复制到堆中。

相关文章

  • iOS block 为什么官方文档建议用 copy 修饰

    一、block 的三种类型block 三种类型:全局 block,堆 block、栈 block。全局 block...

  • iOS 常见面试题 -- block

    一、block的本质 二、block的类型 block 有三种类型分别如下: 如何区分block的类型 三、blo...

  • iOS Block

    Block block 类型 block主要有三种类型 NSGlobalBlock:全局block,存储在全局区 ...

  • iOS Block

    Block的分类 Block有三种类型:全局Block,堆区Block,栈区Block 全局Block 当Bloc...

  • Block实现原理

    主要介绍block的类型和底层分析 block类型 block主要由三种类型 NSGlobalBlock:全局bl...

  • OC底层探索26、Block 原理

    一、block简介 1、block的三种类型 NSGlobalBlock - 全局 block NSMallocB...

  • OC底层-block底层原理探究

    一、block的常见三种类型 1.1 NSGlobalBlock NSGlobalBlock 全局类型block,...

  • iOS底层-Block底层原理

    block类型 block主要有三种类型 __NSGlobalBlock__:全局block,存储在全局区 此时的...

  • block总结

    block声明 block的定义方式(三种) block 调用 通过typedef声明一个block的类型 注意:...

  • Block原理分析

    block类型 我们都知道block有三种类型:NSGlobalBlock、NSStackBlock、NSMall...

网友评论

      本文标题:浅谈block(三)三种类型的block

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