- Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.Their values are taken at the point of the block exPRession within the program. In nested blocks, the value is captured from the nearest enclosing scope.
-(void )test3{ NSString *_person2=@"person2"; NSMutableArray *_listTest=[[NSMutableArray alloc]init]; //初始值 NSLog(@"init _person2:%@,%p",_person2,_person2); NSLog(@"init _listTest:%@,%p",_listTest,_listTest); void (^myBlock)(int) = ^(int num) { //block內賦值 // _weakPerson2=@"person22"; NSLog(@"excuteing _person2:%@,%p",_person2,_person2); NSLog(@"excuteing _listTest:%@,%p",_listTest,_listTest); }; //修改前賦值 _person2=@"person22"; [_listTest addObject:@"1212"]; NSLog(@"excutebefore _person2:%@,%p",_person2,_person2); NSLog(@"excutebefore _listTest:%@,%p",_listTest,_listTest); myBlock(1); //block執行后 NSLog(@"excuteafter _person2:%@,%p",_person2,_person2); NSLog(@"excuteafter _listTest:%@,%p",_listTest,_listTest);}
輸出一下結果:
2014-07-29 11:05:29.460 Test[2540:60b] init _person2:person2,0xb18ec2014-07-29 11:05:29.463 Test[2540:60b] init _listTest:(),0x17d985602014-07-29 11:05:29.464 Test[2540:60b] excutebefore _person2:person22,0xb193c2014-07-29 11:05:29.465 Test[2540:60b] excutebefore _listTest:( 1212),0x17d985602014-07-29 11:05:29.467 Test[2540:60b] excuteing _person2:person2,0xb18ec2014-07-29 11:05:29.468 Test[2540:60b] excuteing _listTest:( 1212),0x17d985602014-07-29 11:05:29.470 Test[2540:60b] excuteafter _person2:person22,0xb193c2014-07-29 11:05:29.471 Test[2540:60b] excuteafter _listTest:( 1212),0x17d98560
struct __block_impl { void *isa; int Flags; int Reserved; void *FuncPtr;};
struct __KDBlockTest__test3_block_impl_0 { struct __block_impl impl; struct __KDBlockTest__test3_block_desc_0* Desc; NSString *_person2; NSMutableArray *_listTest; __KDBlockTest__test3_block_impl_0(void *fp, struct __KDBlockTest__test3_block_desc_0 *desc, NSString *__person2, NSMutableArray *__listTest, int flags=0) : _person2(__person2), _listTest(__listTest) { impl.isa = &_NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc; }};
//block實現的函數
static void __KDBlockTest__test3_block_func_0(struct __KDBlockTest__test3_block_impl_0 *__cself, int num) { NSString *_person2 = __cself->_person2; // bound by copy NSMutableArray *_listTest = __cself->_listTest; // bound by copy NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_4,_person2,_person2); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_5,_listTest,_listTest); }
//block對象的描述信息(大小等等)
static struct __main1_block_desc_0 { size_t reserved; size_t Block_size;} __main1_block_desc_0_DATA = { 0, sizeof(struct __main1_block_impl_0)};
//這是objc測試函數test
static void _I_KDBlockTest_test3(KDBlockTest * self, SEL _cmd) { NSString *_person2=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_1; NSMutableArray *_listTest=((id (*)(id, SEL))(void *)objc_msgSend)((id)((id (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSMutableArray"), sel_registerName("alloc")), sel_registerName("init")); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_2,_person2,_person2); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_3,_listTest,_listTest); void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test3_block_impl_0((void *)__KDBlockTest__test3_block_func_0, &__KDBlockTest__test3_block_desc_0_DATA, _person2, _listTest, 570425344); _person2=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_6; ((void (*)(id, SEL, id))(void *)objc_msgSend)((id)_listTest, sel_registerName("addObject:"), (id)(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_7); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_8,_person2,_person2); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_9,_listTest,_listTest); ((void (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 1); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_10,_person2,_person2); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_11,_listTest,_listTest);}
簡單分析block截獲變量:
void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test3_block_impl_0((void *)__KDBlockTest__test3_block_func_0, &__KDBlockTest__test3_block_desc_0_DATA, _person2, _listTest, 570425344);
: _person2(__person2), _listTest(__listTest)
_person2=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_6; ((void (*)(id, SEL, id))(void *)objc_msgSend)((id)_listTest, sel_registerName("addObject:"), (id)(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_7);
((void (*)(__block_impl *))((__block_impl *)testBlock)->FuncPtr)((__block_impl *)testBlock);
其實還是調用了block對象里的函數對象(_block_imp1)的函數指針(FuncPtr) 所指向的函數__main1_block_func_0,并把block自己作為參數傳遞進去。
static void __KDBlockTest__test3_block_func_0(struct __KDBlockTest__test3_block_impl_0 *__cself, int num) { NSString *_person2 = __cself->_person2; // bound by copy NSMutableArray *_listTest = __cself->_listTest; // bound by copy NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_4,_person2,_person2); NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_6946c5_mi_5,_listTest,_listTest); }
總結:對于局部變量,變量不加__block修飾符,在block內部是無法修改變量的值。而且
新聞熱點
疑難解答