【Objective-C高级编程】iOS与OS X多线程和内存管理(六) __block 说明符
int val = 0 ; void (^blk)(void) = ^{ val = 1; };
int global_val = 1; static int static_global_val= 2; int main () { static int static_val =3; void (^blk)(void) = ^{ global_val *= 1; static_global_val *= 2; static_val *=3; }; return 0; }
转换之后为:
int global_val = 1; static int static_global_val= 2; struct __block_impl { void * isa; int Flags; int Reserved; void *FuncPtr; }; struct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0 *Desc; int *static_val; __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_static_val, int flags = 0):static_val(_static_val) { impl.isa = &_NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc; } }; static void __main_block_func_0 (struct __main_block_impl_0 *__cself) { int *static_val = __cself ->static_val; global_val *= 1; static_global_val *= 2; (*static_val) *= 3; } static struct __main_block_desc_0 { unsigned long reserved; unsigned long Block_size; } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0) }; int main() { static int static_val = 3; blk = & __main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &static_val); return 0; }
以上的做法是使用静态变量保存指针,然后在blocks的实现中通过指针改变静态变量值。
__block int val = 1; void (^blk)(void) = ^{ val = 1; };
转换为:
struct __block_impl { void * isa; int Flags; int Reserved; void *FuncPtr; }; struct __main_byref_val_0 { void *__isa; __Block_byref_val_0 *__forwarding; int __flags; int __size; int val; }; struct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0 *Desc; __Block_byref_val_0 *val; __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_val_0 *val, int flags = 0):val(i_val->__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_val_0 *val = __cself ->val; val->__forwarding->val = 1; } static void __main_block_copy_0 (struct __main_block_impl_0 *dst, struct __main_block_impl_0 *src) { _Block_object_assign (&dst->val, src->val, BLOCK_FIELD_IS_BYREF); } static void __main_block_dispose_0(struct __main_block_imp1_0 *src) { _Block_object_dispose(src->val, BLOCK_FIELD_IS_BYREF); } static struct __main_block_desc_0 { unsigned long reserved; unsigned long Block_size; void (*copy)(struct __main_block_impl_0 *, struct __main_block_impl_0 *); void (*dispose)(struct __main_block_impl_0*); } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0; __main_block_dispose_0; }; int main() { __Block_byref_val_0 val ={0, &val, 0, sizeof(__Block_byref_val_0), 10}; static int static_val = 3; blk = & __main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &val, 0x22000000); return 0; }
① 由上可知,__block 修饰的int变量,变成了结构体实例。即__Block_byref_val_0 的自动变量。
类 | 设置对象的存储域 |
_NSConcreteStackBlock | 栈 |
_NSConcreteGlobalBlock | 程序的数据区域(.data区) |
_NSConcreteMallocBlock | 堆 |
即使在函数内而不再记述广域变量的地方使用Block语法时,只要Block不截获自动变量值,就可以将Block用结构体实例设置在程序的数据区域。
① Block 超出变量作用域可存在的原因
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。