block 之 block的底层实现

作者: 欣东 | 来源:发表于2016-05-15 17:09 被阅读311次

前言

最近在总结关于block的东西,可能会写几篇关于block的博客,语法那些就不说,这里提供一个语法的入口,我们主要探究block的底层实现、block引用局部变量、block的内存管理,今天先讲下block的底层实现。

block实例

#import <Foundation/Foundation.h>

void hello_(){
    int i = 2;
    int j = 3;
    long (^myBlock)(void) = ^long(){
        return i*j*10;
    };
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
 
    }
    return 0;
}

定义hello方法是方便我们等下查看编译代码的时候准确定位myBlock的实现。用clang将objected-C 代码编译为C++代码。

控制台命令:clang -rewrite-objc main.m 

我们打开main.cpp文件,定位到以下代码:

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

这是block基类的定义,所有block都继承于它,拥有它以下那些属性:
isa是指向该block的类型的类,也就是我们理解的对象指针;
Flags包含了引用计数;
Reserved:保留变量,我的理解是表示block内部的变量数;
FuncPtr:函数指针,指向具体block实现的函数的调用地址;

struct __hello__block_impl_0 {
  struct __block_impl impl;
  struct __hello__block_desc_0* Desc;
  int i;
  int j;
  __hello__block_impl_0(void *fp, struct __hello__block_desc_0 *desc, int _i, int _j, int flags=0) : i(_i), j(_j) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

这是myBlock的定义,它的结构体以hello打头,代表myBlock位于hello函数里,这是block的命名方式。__hello__block_desc_0指的是myBlock的描述。

static long __hello__block_func_0(struct __hello__block_impl_0 *__cself) {
  int i = __cself->i; // bound by copy
  int j = __cself->j; // bound by copy

        return i*j*10;
    }

myBlock内函数的具体实现,注意bound by copy,block对外部引用变量做只读拷贝,还有另外的一种情况,在以后讲到关于block引用局部变量的时候会说。

static struct __hello__block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __hello__block_desc_0_DATA = { 0, sizeof(struct __hello__block_impl_0)};

这是myBlock的具体描述

void hello_(){
    int i = 2;
    int j = 3;
    long (*myBlock)(void) = ((long (*)())&__hello__block_impl_0((void *)__hello__block_func_0, &__hello__block_desc_0_DATA, i, j));
}

myBlock实例变量的定义

做下小小总结

block是对象;
编译器会根据block捕获的局部变量,生成具体的结构体定义。block内部的代码将会提取出来,成为一个单独的C函数(eg:__hello__block_func_0)。创建block时,实际就是在方法中声明一个struct,并且初始化该struct的成员。而执行block时,就是调用那个单独的C函数,并把该struct指针传递过去;
block中包含了被引用的局部变量(由struct持有),也包含了控制成分的代码块(由函数指针持有),符合闭包(closure)的概念。

相关文章

  • block 之 block的底层实现

    前言 最近在总结关于block的东西,可能会写几篇关于block的博客,语法那些就不说,这里提供一个语法的入口,我...

  • iOS Block 部分一

    主要讲解 Block 的底层实现原理; Block部分一Block部分二Block部分三Block知识点总结 基础...

  • iOS底层探索之Block(二)——如何解决Block循环引用问

    Block你知道几种?Block的循环引用你有几种解决办法呢? iOS底层探索之Block(一)——初识Block...

  • iOS底层原理 - 窥探Block的本质(一)

    通过窥探Block的底层实现,解答以下问题 1.Block底层数据结构是什么,本质是什么2.Block与其所访问的...

  • Objective-C底层探究之block(二)

    Objective-C底层探究之block(一) 从前面我们知道了block调用其实就是函数的调用。block本身...

  • Block

    1、block的定义和使用 2、Block的底层基本结构 通过clang命令查看编译器是如何实现Block的,在终...

  • Block经典问题循环引用&解决

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 1.循环引用怎么产生的...

  • Block探索

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 程序占用内存分类 栈区...

  • Block底层分析

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 1. 研究工具:cla...

  • Block底层原理分析

    iOSBlock底层原理解析 目录 Block底层解析什么是block?block编译转换结构block实际结构b...

网友评论

    本文标题:block 之 block的底层实现

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