前言
这部分探索 block底层原理 的文章也是之前整理在个人笔记中的, 看了看内容还不少, 所以专门开了一个文集, 分多篇分享出来, 有误之处还望指出, 不胜感激。
ps: 简书好像不支持目录[TOC]啊, 难受。这篇就权当个索引吧。
1.1 block 简介:
block 是能够捕获外部变量的匿名函数, 在 iOS4 中引入, 是对C语言的扩充, C语言本身不存在这样的匿名函数。
1.2 block 本质:
block 本质上是封装了函数调用(函数指针)以及函数调用环境(捕获到的参数)的OC对象。既然是OC对象, 那就是一个结构体, 其结构体内部也有一个isa指针。
1.3 block 类型:
block 有3种类型: _NSConcreteStackBlock, _NSConcreteMallocBlock, _NSConcreteGlobalBlock。
通过调用 class方法 可查看block具体类型:
// __NSGlobalBlock__ : __NSGlobalBlock : NSBlock : NSObject
void (^block)(void) = ^{
NSLog(@"Hello");
};
NSLog(@"%@", [block class]); // __NSGlobalBlock__
NSLog(@"%@", [block class].superclass); // __NSGlobalBlock
NSLog(@"%@", [block class].superclass.superclass); // NSBlock
NSLog(@"%@", [block class].superclass.superclass.superclass); // NSObject
可见: block 最终都是继承自NSBlock类型, 而NSBlock继承于NSObjcet。那么block其中的isa指针其实是来自NSObject中的, 这也更加印证了block 的本质就是OC对象。
1.4 block 存储域:
block 存储域就是这个block在内存中的位置。存储域与block类型密切相关。
MRC下 可能存放在3个地方: 代码区、堆区、栈区
ARC 下 可能存放在2个地方: 代码区 、 堆区。
详见:
《block 底层探索 - 类型与存储域》
1.5 block 底层C++源码:
在fileName.m中实现一个简单的block;
利用终端命令 $ clang -rewrite-objc fileName.m 编译生成C++代码, 在项目目录下找到相应的.cpp文件;
这里先简单介绍几个重要的结构体和函数:
__main_block_impl_0: 结构体, 初始化后赋值给block变量;
__block_impl: 结构体, 封装了block的isa和函数指针;
__main_block_desc_0: 结构体, 封装了block的描述;
__main_block_func_0: 函数, 封装了代码块中的代码;
详见:
《block 底层探索 - C++源码分析》
1.6 block 捕获变量:
一般变量可以分为以下5种: 自动变量(局部变量)、静态局部变量、全局变量、静态全局变量、函数参数。
block 捕获外部变量, 可以分为: 全局变量、静态全局变量、静态局部变量、__block局部变量。
2.0 参考的文章
http://www.jianshu.com/p/bb63aabdb2db
https://www.jianshu.com/p/a11337dbc8fd
https://www.jianshu.com/p/ee9756f3d5f6
https://www.jianshu.com/p/404ff9d3cd42
http://www.cocoachina.com/ios/20150106/10850.html
http://www.cocoachina.com/cms/wap.php?action=article&id=23147
https://blog.csdn.net/u014600626/article/details/78697535
网友评论