上一篇 我們了解了block全局變量的使用,靜態變量和全局變量一樣,可以直接在block內部使用,也可以在block內部修改
引用官方文檔:
Global variables are accessible, including static variables that exist within the enclosing lexical scope.
我們來看一段代碼:
聲明一個靜態變量,在block內部修改
static NSString * _para1;-(void )test4{ _para1=@"para1"; //初始值 NSLog(@"init para1:%@,%p,%p",_para1,&_para1,_para1); void (^myBlock)(int) = ^(int num) { //block內賦值 _para1=@"para3"; NSLog(@"excuteing para1:%@,%p,%p",_para1,&_para1,_para1); }; //修改前賦值 _para1=@"para2"; NSLog(@"excutebefore para1:%@,%p,%p",_para1,&_para1,_para1); myBlock(1); //block執行后 NSLog(@"excuteafter para1:%@,%p,%p",_para1,&_para1,_para1);}
輸出:
2014-07-28 17:05:47.701 Test[2307:60b] init para1:para1,0x39bb0,0x399e42014-07-28 17:05:47.704 Test[2307:60b] excutebefore para1:para2,0x39bb0,0x39a242014-07-28 17:05:47.705 Test[2307:60b] excuteing para1:para3,0x39bb0,0x39a042014-07-28 17:05:47.706 Test[2307:60b] excuteafter para1:para3,0x39bb0,0x39a04
從日志可以看出,block里變量地址和外部的是一樣的,而且可以修改靜態變量。
我們看一下轉換后的代碼:
static NSString * _para1;struct __KDBlockTest__test4_block_impl_0 { struct __block_impl impl; struct __KDBlockTest__test4_block_desc_0* Desc; __KDBlockTest__test4_block_impl_0(void *fp, struct __KDBlockTest__test4_block_desc_0 *desc, int flags=0) { impl.isa = &_NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc; }};
因為靜態對象存在靜態區(全局區)從創建到程序銷毀一直存在,block內部沒有聲明對應的成員。下面是我們的test4 函數:
static void _I_KDBlockTest_test4(KDBlockTest * self, SEL _cmd) { _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_1; NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_2,_para1,&_para1,_para1); void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test4_block_impl_0((void *)__KDBlockTest__test4_block_func_0, &__KDBlockTest__test4_block_desc_0_DATA); _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_5; NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_6,_para1,&_para1,_para1); ((void (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 1); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_7,_para1,&_para1,_para1);}
block初始化,傳入實現函數的指針和描述函數,并沒有其他參數。
void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test4_block_impl_0((void *)__KDBlockTest__test4_block_func_0, &__KDBlockTest__test4_block_desc_0_DATA);
我們來看下實現的函數,直接引用了靜態變量
static void __KDBlockTest__test4_block_func_0(struct __KDBlockTest__test4_block_impl_0 *__cself, int num) { _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_3; NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_4,_para1,&_para1,_para1); }
不考慮循環引用的基礎上,靜態變量和成員變量使用上方法大致一樣,但是原理上還是有區別的。
新聞熱點
疑難解答