开发中,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 *)做强制类型转换