block的实现原理
来源:互联网 发布:linux编程基础 编辑:程序博客网 时间:2024/05/20 01:37
block的实现原理
将代码在Xcode中编写后,编译查看结果,test3和test4的结果我想大家都能猜到,基本C语言的一致.
但test1和test2的实现原理是比较重要的,运行后对结果的怎么实现的无法理解.
代码如下:
void test1() {int a = 8;void (^myBlock)() = ^{NSLog(@"a = %d",a);};a = 12;myBlock();}void test2() {__block int a = 8;void (^myBlock)() = ^{NSLog(@"a = %d",a);};a = 12;myBlock();}void test3() {static int a = 8;void (^myBlock)() = ^{NSLog(@"a = %d",a);};a = 12;myBlock();}int a = 8;void test4() {void (^myBlock)() = ^{NSLog(@"a = %d",a);};a = 12;myBlock();}int main(int argc, const char * argv[]) {test4();return 0;}想要理解block的内部实现原理,我们需要将代码编译成cpp文件.在terminal中以clang -rewrite-objc main.m 指令将其编译生成 main.cpp文件,以下代码是截取重要部分的内容.
-------------------------------------------------------------------------- 美丽的分割线 cpp分析部分 ---------------------------------------------------------------
//main函数
int main(int argc, const char * argv[]) {test1();return 0;}
//block的实现部分
//1.从这里开始
重点:
//1.1.a的值被初始化成8
//1.2.被传入myBlock的是a,因此被传入的是a的值8.
//1.3由于传入的是8常量,因此在block中不能给a重新赋值.
//1.4block中传入3个参数,
//1.5注意此时a的值8已传入block中,此时可以理解为:block实现部分已经就绪,只欠西北风了</span>
//1.6重新给a赋值12,这个结赋值不会影响block中的a的值,因为block的参数已经传入了,更新后不会再传入
//1.7执行block代码
void test1() {//1.1 int a = 8;//1.2//1.3//1.4//1.5 void (*myBlock)() = (void (*)())&__test1_block_impl_0((void *)__test1_block_func_0, &__test1_block_desc_0_DATA, a);//1.6 a = 12;//1.7 ((void (*)(__block_impl *))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock);}
//2.原先a的值以形参_a的形式传进来,并赋给a,因此block中的a的值为8
/**
* __test1_block_impl_0的实现部分
*
* @param fp 函数指针
* @param desc 结构体__test1_block_impl_0的字节长度
* @param _a 形参a
* @param flags 忽视它
*
*/
struct __test1_block_impl_0 {struct __block_impl impl;struct __test1_block_desc_0* Desc;int a;__test1_block_impl_0(void *fp, struct __test1_block_desc_0 *desc, int _a, int flags=0) : a(_a) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}};
/**
* block函数内部功能
*
* @param __cself 结构体的内部变量的引用
*/
//将__test1_block_impl_0中的a的值传给局部变量a中,将会打印该a的值.
static void __test1_block_func_0(struct __test1_block_impl_0 *__cself) {int a = __cself->a; // bound by copyNSLog((NSString *)&__NSConstantStringImpl__var_folders_16_2nnq6r3n5sq_4ynmhpf31szm0000gp_T_main_d05376_mi_0,a);}
//内部两个参数,第一个为保留,第二个为block的字节长度,通过sizeof(struct __test1_block_impl_0)得到值
static struct __test1_block_desc_0 {size_t reserved;size_t Block_size;} __test1_block_desc_0_DATA = { 0, sizeof(struct __test1_block_impl_0)};
//这是block的结构,是个结构体,记住block是个结构体
struct __Block_byref_a_0 {void *__isa;__Block_byref_a_0 *__forwarding; int __flags; int __size; int a;};
-------------------------------------------------------------------------- 美丽的分割线 test2分析---------------------------------------------------------------
//================ test2 =================================================================struct __test2_block_impl_0 {struct __block_impl impl;struct __test2_block_desc_0* Desc;__Block_byref_a_0 *a; // by ref__test2_block_impl_0(void *fp, struct __test2_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}};static void __test2_block_func_0(struct __test2_block_impl_0 *__cself) {__Block_byref_a_0 *a = __cself->a; // bound by refNSLog((NSString *)&__NSConstantStringImpl__var_folders_16_2nnq6r3n5sq_4ynmhpf31szm0000gp_T_main_d05376_mi_1,(a->__forwarding->a));}static void __test2_block_copy_0(struct __test2_block_impl_0*dst, struct __test2_block_impl_0*src) {_Block_object_assign((void*)&dst->a, (void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}static void __test2_block_dispose_0(struct __test2_block_impl_0*src) {_Block_object_dispose((void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}static struct __test2_block_desc_0 {size_t reserved;size_t Block_size;void (*copy)(struct __test2_block_impl_0*, struct __test2_block_impl_0*);void (*dispose)(struct __test2_block_impl_0*);} __test2_block_desc_0_DATA = { 0, sizeof(struct __test2_block_impl_0), __test2_block_copy_0, __test2_block_dispose_0};void test2() { __attribute__((__blocks__(byref))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 8};}
/**
* test2与test1的区别在于此,将block中传入的不是a的值,而是a的地址
*
* @param myBlock 函数名
* 因此在block中可以重新对a进行赋值
*/
void (*myBlock)() = (void (*)())&__test2_block_impl_0((void *)__test2_block_func_0, &__test2_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344); (a.__forwarding->a) = 12; ((void (*)(__block_impl *))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock);}
只分析了test1和test2,我想test3和test4比较好理解.
-------------------------------------------------------------------------- 美丽的分割线 test3和test4 cpp代码,自行分析---------------------------------------------------------------
/================ test3 =================================================================struct __test3_block_impl_0 {struct __block_impl impl;struct __test3_block_desc_0* Desc;int *a;__test3_block_impl_0(void *fp, struct __test3_block_desc_0 *desc, int *_a, int flags=0) : a(_a) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}};static void __test3_block_func_0(struct __test3_block_impl_0 *__cself) {int *a = __cself->a; // bound by copyNSLog((NSString *)&__NSConstantStringImpl__var_folders_16_2nnq6r3n5sq_4ynmhpf31szm0000gp_T_main_d05376_mi_2,(*a));}static struct __test3_block_desc_0 {size_t reserved;size_t Block_size;} __test3_block_desc_0_DATA = { 0, sizeof(struct __test3_block_impl_0)};void test3() { static int a = 8; void (*myBlock)() = (void (*)())&__test3_block_impl_0((void *)__test3_block_func_0, &__test3_block_desc_0_DATA, &a); a = 12; ((void (*)(__block_impl *))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock);}//================ test4 =================================================================int a = 8;struct __test4_block_impl_0 {struct __block_impl impl;struct __test4_block_desc_0* Desc;__test4_block_impl_0(void *fp, struct __test4_block_desc_0 *desc, int flags=0) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}};static void __test4_block_func_0(struct __test4_block_impl_0 *__cself) {NSLog((NSString *)&__NSConstantStringImpl__var_folders_16_2nnq6r3n5sq_4ynmhpf31szm0000gp_T_main_d05376_mi_3,a);}static struct __test4_block_desc_0 {size_t reserved;size_t Block_size;} __test4_block_desc_0_DATA = { 0, sizeof(struct __test4_block_impl_0)};void test4() { void (*myBlock)() = (void (*)())&__test4_block_impl_0((void *)__test4_block_func_0, &__test4_block_desc_0_DATA); a = 12; ((void (*)(__block_impl *))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock);}
test3是由static声明,test4是全局变量,因此内从中只有一份.
---end
- Block的实现原理
- block的实现原理
- block的实现原理
- block的实现原理(整理)
- block的用法 实现原理
- block的实现原理(二)
- Block的内部实现原理
- Objective-C的Block的实现原理
- Block的使用与实现原理
- block 实现原理
- block底层实现原理
- block实现原理详解
- block 实现原理详解
- Block实现原理
- Block实现原理
- block实现原理?
- Block实现原理
- Block 的原理
- android对handler及asynctask的一个例子
- Js jq获取select值
- poj 3639 dp
- Gnome的配置参数管理
- 对Memcached使用的总结和使用场景
- block的实现原理
- AMQP机制
- WEB版一次选择多个文件进行批量上传(Plupload)的解决方案
- 详解UML中的关系(泛化、实现、依赖、关联【聚合、组合】)
- PUUPLOAD 上传文件范例
- 使用官方Fedora22 ISO镜像制作OpenStack云镜像
- Ajax
- 百度地图简单使用
- 关于apache以fastcgi模式运行php的错误理解纠正