美文网首页iOS DeveloperiOS开发技巧
Objective-C Block(闭包)实现

Objective-C Block(闭包)实现

作者: 尘絮缘12138 | 来源:发表于2015-12-27 12:52 被阅读351次

Block的实质

Block我想写OC的都不会陌生,在项目中我们经常会使用block作为数据处理后的回调,例如通知主线程UI更新等。Block的语法看上去很特别,但是它实际上是作为及普通的C源代码来处理的。含有Block的源代码转换为一般的C语言代码,之后作为C语言代码被编译。

这里插句题外话,很多动态语言底层都是C或者C++,例如Python,ruby底层都是C,这两门语言里面也有block的概念,只不过在python里称为lambda。所以他们的实现方式是相似的。

OK,回到正题。首先,我们通过clang -rewrite-objc filename(clang是编译指令) 将含有block的源文件转换为C源代码,OC源代码如下:

int main() {
  //block实现
  void (^test)(void) = ^{
     printf("Hello World\n");
  };

  test();

  return 0;
}

代码很简单,只是打印一个字符串.但是转换后却又10000+的代码,但是和block相关的代码却在底部,只有几十行而已,我们来看下:

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

<br />

  static void __main_block_func_0(struct __main_block_impl_0 *__cself){
      printf("Hello World!\n");
  }

<br />

  static struct __main_block_desc_0 {
    size_t reserved;
  size_t Block_size;
  } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

<br />

   int main() {
   void (*test)(void) = (void (*)())&__main_block_impl_0((void *)__main_block_func_0,       
    &__main_block_desc_0_DATA);
  ((void (*)(__block_impl *))((__block_impl *)test)->FuncPtr)
  ((__block_impl *)test);

  return 0;
}

上面四段代码就是一个简单Block的C版本,下面我们一一讲解下。

  static void __main_block_func_0(struct __main_block_impl_0 *__cself){
    printf("Hello World!\n");
  }

这段代码代表的就是block的实现,其中__main_block_func_0代表的是主函数中第0个函数,其参数是Block本身,类似C++的this指针和OC的self.

下面我们来看看cself的类型:__main_block_impl_0

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

可以看到这个类型是个结构体,里面有两个结构体参数,外加一个构造方法.其中变量impl是另一个结构体,我们来看下它的内容:

  struct __block_impl{
      void *isa;
      int Flags;
      int Reserved;
      void *FuncPtr;
  }

除了耳熟能详的的isa指针外,我们还看到flags,估计是某些标志;reserved,升级预留区域,以及一个函数指针.

再看看Desc的结构:

struct __main_block_desc_0{
unsigned long reserved;
unsigned long Block_size;
}

代表的是版本升级预留区域,和block大小.

下面我们看看其构造函数的调用:

  void (*test)(void) = (void (*)())&__main_block_impl_0((void
    *)__main_block_func_0, &__main_block_desc_0_DATA);  
  }

其实就是将__main_block_impl_0结构体赋值给test变量,顺带初始化其他属性.
之后,调用:

  ((void (*)(__block_impl *))((__block_impl *)test)->FuncPtr)
   ((__block_impl *)test);  
  }

这其实就是一个简单的函数指针调用函数,类似(*name)(paramters..)调用.

致此,block的实质就讲的差不多了,漏了一个_NSConcreteStackBlock下次再讲吧.

相关文章

  • block总结(温故而知新)

    Block block实际上是Objective-C语言对闭包的实现。 闭包(Closure) 闭包就是一个函数,...

  • Block原理解析

    Block是什么? Block实际上是Objective-C对闭包的实现。 关于闭包的概念:In programm...

  • Objective-c Block

    block Block简介 block�实际上是Objective-c对闭包的实现。闭包允许一个函数访问声明该函数...

  • block原理

    c语言中的闭包 block解答题 block结构 唐巧之谈Objective-C block的实现

  • Block原理解析

    Block实际上是Objective-C对闭包的实现。 关于闭包的概念: In programming langu...

  • block原理

    1. block的定义 block是Objective-C对于闭包的实现(闭包是一个函数<或者指向函数的指针>加上...

  • Block底层学习

    Block底层本质 block就是Objective-C对闭包的实现,闭包就是一个没有名字的函数或者指向函数的指针...

  • block的使用

    block实际上就是Objective-C语言对闭包的实现。 NSString * ( ^ myBlock )( ...

  • 04·iOS 面试题·Block 的原理,Block 的属性修饰

    前言 Block 在平时开发中经常使用,它是 Objective-C 对 闭包 是实现,定义如下: Block 是...

  • iOS里关于block的一些理解

    介绍 block实际上就是Objective-C语言对于闭包的实现。block配合上dispatch_queue,...

网友评论

    本文标题:Objective-C Block(闭包)实现

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