对于大多数人来讲,block内部到底是怎样实现的呢?我们可以借助clang将其编译成为c++的代码,就可以看出,block到底是什么东西,

先来看这样一个问题,

<!-- lang: cpp -->
int age = 10;
void (^block)() = ^{
NSLog(@"%d",age);
};
age = 30;
block();//10

以及下面的这一段代码

<!-- lang: cpp -->
__block int age = 10;
void (^block)() = ^{
NSLog(@"%d",age);
};
age = 30;
block();//30

你会发现这两个结果是不同的, 
第一个输出10,第二个输出的是30

要想知道这里面干了些什么!需要我们将其编译成为C++代码,看下里面到底搞了些什么? 
使用终端,转到mian.m文件下,使用如下代码 clang -rewrite-objc main.m 将其编译生成 main.cpp文件 
这时候,我们打开mian.cpp便知 在文件的最底下main函数中

<!-- lang: cpp -->
int main(int argc, const char * argv[])

{

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

    __attribute__((__blocks__(byref))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), 10};
void (*block)() = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age, 570425344);
(age.__forwarding->age) = 30;
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block); }
return 0;

}

block内部是调用了一个结构体中的函数: 
static struct main_block_desc_0 { 
size_t reserved; 
size_t Block_size; 
void (copy)(struct __main_block_impl_0, struct 
main_block_impl_0); 
void (
dispose)(struct __main_block_impl_0*); 
}

然后经过分析该c++文件我们知道 
block实际上是: 指向结构体的指针 
编译器会将block的内部代码生成对应的函数

而在mian.m中,调用普通的int变量时,传过来的age其实是一个值传递,而__block则是引用传递! 
所以,才是如上的结果!

block 实现原理详解(一)的更多相关文章

  1. 块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解

    CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...

  2. 节点地址的函数list_entry()原理详解

    本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...

  3. Influxdb原理详解

    本文属于<InfluxDB系列教程>文章系列,该系列共包括以下 15 部分: InfluxDB学习之InfluxDB的安装和简介 InfluxDB学习之InfluxDB的基本概念 Infl ...

  4. Namenode HA原理详解(脑裂)

    转自:http://blog.csdn.net/tantexian/article/details/40109331 Namenode HA原理详解 社区hadoop2.2.0 release版本开始 ...

  5. I2C 基础原理详解

    今天来学习下I2C通信~ I2C(Inter-Intergrated Circuit)指的是 IC(Intergrated Circuit)之间的(Inter) 通信方式.如上图所以有很多的周边设备都 ...

  6. Zigbee组网原理详解

    Zigbee组网原理详解 来源:互联网 作者:佚名2015年08月13日 15:57   [导读] 组建一个完整的zigbee网状网络包括两个步骤:网络初始化.节点加入网络.其中节点加入网络又包括两个 ...

  7. SSL/TLS 原理详解

    本文大部分整理自网络,相关文章请见文后参考. SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰.正文开始. 1. SSL/TLS概览 1 ...

  8. 锁之“轻量级锁”原理详解(Lightweight Locking)

    大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意. 原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖 ...

  9. [转]js中几种实用的跨域方法原理详解

    转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...

随机推荐

  1. Web服务器处理HTTP压缩之gzip、deflate压缩

    现如今在处理http请求的时候,由于请求的资源较多,如果不启用压缩的话,那么页面请求的流量将会非常大.启用gzip压缩,在一定程度上会大大的提高页面性能.   目录 一.什么是gzip 二.什么是de ...

  2. linux下的终端模拟器urxvt的配置

    内容所在的文件: ~/.Xdefaults 文件的内容: URxvt.background:[90]#000000URxvt.foreground:#ffffffURxvt.colorBD:Gray9 ...

  3. nginx for windows中的一项缺陷

    按照官网上的说法,使用 start nginx 启动 nginx,使用 nginx -s quit 可以优雅地退出. 经实验,使用 start nginx 之后,会启动两个 nginx 的进程,据官网 ...

  4. 博创arm板编译内核makefile不兼容问题解决

    导致这种结果的是:Make工具对低版本内核的Makefile一些旧的规则兼容不好,我们只需修改对应的Makefile. 改1:: 原始的:          大概在 1503行 / %/: prepa ...

  5. android之‘com.example.android.apis.view’的代码段

    1.AutoCompleteTextView ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, and ...

  6. Rsync详解

    Rsync详解 1.什么是RsyncRsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.Rsync使用所谓的“Rsync算法”来使本 ...

  7. javascript 深拷贝

    javascript存在两种拷贝:浅拷贝.深拷贝. 它们最大的区别在于引用类型的拷贝上:浅拷贝复制的是引用(指针),深拷贝复制的是里面的数据. 由于以上原因,在下例中 浅拷贝修改的值影响了声明的对象a ...

  8. sql创建删除修改表的基本操作

    1 建立表格 在建立好数据库以后,就可以根据储存资料的需求,使用SQL叙述建立所有需要的表格(table).建立表格的设定非常多,以建立"world.city"表格来说,它的叙述会 ...

  9. linux设备驱动归纳总结(五):4.写个简单的LED驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-84693.html linux设备驱动归纳总结(五):4.写个简单的LED驱动 xxxxxxxxxxx ...

  10. jQuery上传插件,文件上传测试用例

    jQuery上传插件,文件上传测试用例 jQuery File Upload-jQuery上传插件介绍http://www.jq22.com/jquery-info230 jQuery File Up ...