Objective-C中的Block本质是一个对象。 也可以把block理解为闭包。
void (^block变量名)(NSString* 参数1...);
block变量名 = ^(NSString* 参数1...){
函数体
};
block变量名();
在GCD中给我们提供了一个无返回值,无参数的block定义。
@property (nonatomic, copy) dispatch_block_t block;


struct Block_descriptor {
unsigned long int reserved;
unsigned long int size;
void (*copy)(void *dst, void *src);
void (*dispose)(void *);
};
struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
/* Imported variables. */
};
分析
不捕获变量。
分配到占上的实例。
堆Block,通常不会在源码中出现。默认当一个block在被copy时,才会将block复制到堆上。
struct __Block_byref_i_0 {
void *__isa;
__Block_byref_i_0 *__forwarding;
int __flags;
int __size;
int i;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_i_0 *i; // by ref
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_i_0 *_i, int flags=0) : i(_i->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
__Block_byref_i_0 *i = __cself->i; // bound by ref
printf("%d\n", (i->__forwarding->i));
(i->__forwarding->i) = 1023;
}
...
__Block_byref_i_0的形式存在,同时在__main_block_func_0中使用的事__Block_byref_i_0的结构体指针,保证改变的是外部的变量的值。__Block_byref_i_0结构体中保存的是捕获的外部变量的地址,forwarding的作用是在拷贝到堆上后,保证指针指向的是堆上的地址。在ARC模式下,将只有全局block和堆block
[1] https://blog.devtang.com/2013/07/28/a-look-inside-blocks/