程序员

block 底层探索 - 纲要索引

2018-05-02  本文已影响175人  felix6

前言

这部分探索 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局部变量。

详见:
block 底层探索 - 变量捕获
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

上一篇下一篇

猜你喜欢

热点阅读