<<<<<<==========================>>>>>>
- 如果有如下代码片段:
NSInteger valOfCopy = 4;
__block NSInteger valOfAddress = 5;
[self setBock:^{
NSLog(@"Test Block ---- valOfCopy: %d", valOfCopy);
NSLog(@"Test Block ---- valOfAddress : %d", valOfAddress);
}];
通过 clang -rewrite-objc 生成的c++代码如下:
<<<<<<==========================>>>>>>
- block 实现定义,每一个block都以此结构开始
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
isa: 指向 _NSConcreteStackBlock
FuncPtr: 为block实现的c方法指针:
- 所有使用 __block 修饰的变量都会有如下结构体:
struct __Block_byref_valOfAddress_0 {
void *__isa;
__Block_byref_valOfAddress_0 *__forwarding;/* 链表 */
int __flags;
int __size;
NSInteger valOfAddress;
};
- 每一个block定义都有一个Desc的如下结构体:
static struct __EZLNAtomicObj__testBlock_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __EZLNAtomicObj__testBlock_block_impl_0*, struct __EZLNAtomicObj__testBlock_block_impl_0*);
void (*dispose)(struct __EZLNAtomicObj__testBlock_block_impl_0*);
} __EZLNAtomicObj__testBlock_block_desc_0_DATA = { 0,
sizeof(struct __EZLNAtomicObj__testBlock_block_impl_0),
__EZLNAtomicObj__testBlock_block_copy_0,
__EZLNAtomicObj__testBlock_block_dispose_0};
- 每一个block的定义类似如下结构体:
struct __EZLNAtomicObj__testBlock_block_impl_0 {
struct __block_impl impl;
struct __EZLNAtomicObj__testBlock_block_desc_0* Desc;
NSInteger valOfCopy; //by value
__Block_byref_valOfAddress_0 *valOfAddress; // by ref
__EZLNAtomicObj__testBlock_block_impl_0(void *fp,
struct __EZLNAtomicObj__testBlock_block_desc_0 *desc,
NSInteger _valOfCopy,
__Block_byref_valOfAddress_0 *_valOfAddress,
int flags=0) :
valOfCopy(_valOfCopy),
valOfAddress(_valOfAddress->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
- 函数指针类型定义
static void __EZLNAtomicObj__testBlock_block_func_0(struct __EZLNAtomicObj__testBlock_block_impl_0 *__cself) {
__Block_byref_valOfAddress_0 *valOfAddress = __cself->valOfAddress; // bound by ref
NSInteger valOfCopy = __cself->valOfCopy; // bound by copy
NSLog((NSString *)&__NSConstantStringImpl__var_folders_k6__hvncg2s7db50p8ngrh2dxhh0000gn_T_EZLNAtomicObj_bd52cc_mi_5, valOfCopy);
NSLog((NSString *)&__NSConstantStringImpl__var_folders_k6__hvncg2s7db50p8ngrh2dxhh0000gn_T_EZLNAtomicObj_bd52cc_mi_6, (valOfAddress->__forwarding->valOfAddress));
}
- block 调用代码
NSInteger valOfCopy = 4;
__attribute__((__blocks__(byref))) __Block_byref_valOfAddress_0 valOfAddress = {(void*)0,(__Block_byref_valOfAddress_0 *)&valOfAddress, 0, sizeof(__Block_byref_valOfAddress_0), 5};
((void (*)(id, SEL, void (*)()))(void *)objc_msgSend)((id)self, sel_registerName("setBock:"), ((void (*)())&__EZLNAtomicObj__testBlock_block_impl_0((void *)__EZLNAtomicObj__testBlock_block_func_0, &__EZLNAtomicObj__testBlock_block_desc_0_DATA, valOfCopy, (__Block_byref_valOfAddress_0 *)&valOfAddress, 570425344)));
void (*Block1)(void) = ((void (*)())&__EZLNAtomicObj__testBlock_block_impl_1((void *)__EZLNAtomicObj__testBlock_block_func_1, &__EZLNAtomicObj__testBlock_block_desc_1_DATA));
((void (*)(id, SEL, void (*)()))(void *)objc_msgSend)((id)self, sel_registerName("setBock:"), (void (*)())((id (*)(id, SEL))(void *)objc_msgSend)((id)Block1, sel_registerName("copy")));
总结:block实际是一个C++对象,包含了blok里引用的变量(值复制)和指针结构体(使用__block修饰),整个block结构体类似一个C++对象,提供一个带参数的构造函数。执行block实际上是对block对象发消息,然后将block的对象作为参数传入,而block对象又定义了一个函数指针,实际上是执行此函数。