首页 > 代码库 > block 块的内部结构
block 块的内部结构
每个oc对象都占据着某个内存区域,因为实例变量的个数及对象所包含的关联数据互不相同,所以每个对象所占的内存区域大小也是有大有小,块本身也是对象,在存放块对象的内存区域中,首个变量是指向Class对象的指针,该指针叫做isa。其余内存里含有块丢向正常运转所需的各种信息。
如下:
块 | |
void* | isa |
int | flags |
int | reserved |
void(*)(void,*..) | invoke |
struct* | descriptor |
捕获到的变量 |
下图为descriptor里的结构描述
块描述符 | |
unsigned long int | reserved |
unsigned long int | size |
void (*)(void *,void*) | copy |
void(*)(void*,void*) | dispose |
在内存布局中,最重要的就是invoke变量,这是个函数指针,只想块的实现代码,函数原型至少接受一个void*型的参数,此参数代表块。刚才说过,块其实就是一种代替函数指针的语法结构,原来使用函数指针时,需要用“不透明的void指针”来传递状态。而改用块之后,则可以把原来用标准C语言特性所编写的代码封装成简明且易用的接口。
descriptor变量是只像结构体的指针,每个块里都包含此结构体,其中声明了块对象的总体大小,还声明了copy与dispose这两个辅助函数所对应的函数指针。辅助函数在拷贝及丢弃块对象时运行,其中会执行一些操作,比方说,前者要保留捕获的对象,而后者将之释放。
块还会把它所捕获的所有变量都拷贝一份,这些拷贝放在descriptor变量后面,捕获了多少个变量,就要占据多少内存空间,请注意,拷贝的对象不是对象本身,而是指向这些对象的指针变量。invoke函数为何需要把块对象作为参数传进来呢?原因就在于,执行块时,要从内存中把这些捕获到的变量读出来。
这里只是帮助理解块对象的内部的结构,实际用处感觉不大。
block 块的内部结构
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。