依照基本数据类型,类推对象类型.[iOS Block Part2]内已经将基本数据类型的block编译后的结构体样式+调用流程展示过了.本篇文章对于这些内容就不再赘述.本篇文章会对对象类型block与基本数据类型block的不同点进行详细讲述.
对象类型
int main(int argc, const char * argv[]) {
NSString * any = [NSString stringWithFormat:@"1"];
void (^test)() = ^ {
NSLog(@"%@",any);
};
test();
return 0;
}
编译结果:
代码连线图还是很复杂,看结构示意图:
block(int)
struct __main_block_impl_0 {
struct __block_impl impl;//block方法实现
struct __main_block_desc_0* Desc;//block的描述
int any;//block捕获了外部变量
};
block(NSString)
struct __main_block_impl_0 {
struct __block_impl impl;//block方法实现
struct __main_block_desc_0* Desc;//block的描述
NSString * any;//block捕获了外部变量
};
对比起来看,对象类型编译后的struct __main_block_impl_0
与基本数据类型编译后的struct __main_block_impl_0
并没有太多的差别.(除了捕获了外部变量int any
VSNSString * any
).
再看看,两方的struct __main_block_desc_0
.
block(int)
struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
}
block(NSString)
struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);//多出来的
void (*dispose)(struct __main_block_impl_0*);//多出来的
}
对象类型编译后的struct __main_block_desc_0
与基本数据类型编译后的struct __main_block_desc_0
相比多出两个函数指针.
那么这两函数指针分别指向下面两个函数:
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {
_Block_object_assign((void*)&dst->any, (void*)src->any, 3/*BLOCK_FIELD_IS_OBJECT*/);
}
static void __main_block_dispose_0(struct __main_block_impl_0*src) {
_Block_object_dispose((void*)src->any, 3/*BLOCK_FIELD_IS_OBJECT*/);
}
那么这两函数又拿来做什么的呢?
注意图片block(NSString)_map
的step1
==>将NSStackBlock
类型的block
进行自动copy转换成NSMallocBlock
类型的block
,多了一步NSString * any
的拷贝.
函数__main_block_copy_0
就是将栈上的NSString * any
拷贝到堆上的.
函数__main_block_dispose_0
就是将堆NSString * any
销毁掉的.
iOS Block Part2中已经说过
NSStackBlock
类型的block
copy转换成NSMallocBlock
类型的block
的过程后面的文章会详细的说,而这里又出个对象的copy,还是那句话:"后面的文章会详细的说".
参考文献:
Block技巧与底层解析 by tripleCC