您的当前位置:首页正文

block到底是什么?我们为什么要用block

来源:华拓网

开发中,block一般应用于反向传值,回调函数,使用block,代码紧凑易读,实在是给开发维护带来极大方便,但是block到底是什么,block的滥用会带来什么问题,block的循环引用原理,又block在内存中是怎样开辟空间,在什么时候会释放没有深入研究过!

先看下官方文档介绍

Block objects are a C-level syntactic and runtime feature. They are similar to standard C functions, but in addition to executable code they may also contain variable bindings to automatic (stack) or managed (heap) memory. A block can therefore maintain a set of state (data) that it can use to impact behavior when executed.

还是建议看下官方文档,介绍的很好!

翻阅一些资料,看到block的数据结构定义,

#1

Struct Block_layout{

void * isa;

int flags;

int reserved;

void (*invoke)(void *,…);

struct Block _descriptor * descript;

/*imported variables*/

}

struct Block_descriptor{

unsigned long int reserved;

unsigned long int size;

void (* copy)(void * dst,void * src);

void(* dispose)(void *);

}

我们可以看出,一个block实例实际上由6部分组成:

1.isa指针,所有对象都有该指针,用于实现对象相关的功能

2.flags,用于按bit位表示一些block的附加信息

3.reserved,保留变量

4.invoke ,函数指针,指向具体的block实现的函数调用地址

5.descriptor ,表示该block的附加信息

6.variables,capture过来的变量,block能够访问外部的局部变量,就是因为将这些变量的地址复制到结构体中,如果这个变量是引用类型,则block会将其引用计数+1

#2 block在内存中的位置

NSGlobalBlock:

NSStackBlock:

NSMallocBlock:

因为block中含有isa指针,这就证明了block同OC中得对象是一样的,这个isa指针被初始化为_NSConcreateStackBlock或者NSConcreateGlobalBlock类的地址

MRC中:block包含局部变量则isa被初始化为NSConcreateStackBlock,否则,被初始化NSConcreateGlobalBlock

ARC中: block中包含有局部变量则isa被初始化为NSConcreateMallocBlock,否则被初始化为NSConcreateGlobalBlock

block可以看做是一个oc对象

#3.Block的拷贝过程

block初始化创建的结构在stack中,而stack空间会被系统重复利用,如果我们想要在以后继续使用该block,就必须要对block进行拷贝,调用block_copy()函数,查看/usr/include/Block.h

Block_copy()实际是一个宏定义,传入的参数(const void *)做强制类型转换