關於block中呼叫外部基本資料型別變數問題
阿新 • • 發佈:2019-01-02
先看兩種方式的程式碼:
- (void)blockDemo1{
__block int num = 10;
int *p = #
NSLog(@"=>%p",p);
// 定義一個block
void (^task)() = ^{
NSLog(@"==>%p-%d",&num,num);
NSLog(@"=>%d",*p);
};
num = 20;
NSLog(@"=>%p",p);
// 執行block
task();
NSLog(@"===>%p-%d",&num,num);
NSLog(@"=>%d",*p);
}
##執行結果
2017-02-21 20:04:00.117 04-Block的面試題[4856:577406] =>0x7fff55e95668
2017-02-21 20:04:00.117 04-Block的面試題[4856:577406] =>0x7fff55e95668
2017-02-21 20:04:00.117 04-Block的面試題[4856:577406] ==>0x600000232958-20
2017-02-21 20:04:00.117 04-Block的面試題[4856:577406] =>10
2017-02-21 20:04:00.117 04-Block的面試題[4856 :577406] ===>0x600000232958-20
2017-02-21 20:04:00.118 04-Block的面試題[4856:577406] =>10
- (void)blockDemo1{
int num = 10;
int *p = #
NSLog(@"=>%p",p);
// 定義一個block
void (^task)() = ^{
NSLog(@"==>%p-%d",&num,num);
NSLog(@"=>%d",*p);
};
num = 20;
NSLog(@"=>%p",p);
// 執行block
task();
NSLog(@"===>%p-%d",&num,num);
NSLog(@"=>%d",*p);
}
##執行結果
2017-02-21 20:05:19.534 04-Block的面試題[4877:578778] =>0x7fff5536766c
2017-02-21 20:05:19.534 04-Block的面試題[4877:578778] =>0x7fff5536766c
2017-02-21 20:05:19.534 04-Block的面試題[4877:578778] ==>0x600000055478-10
2017-02-21 20:05:19.534 04-Block的面試題[4877:578778] =>20
2017-02-21 20:05:19.535 04-Block的面試題[4877:578778] ===>0x7fff5536766c-20
2017-02-21 20:05:19.535 04-Block的面試題[4877:578778] =>20
不同點:是基本資料型別前面加了一個”block”
加”block”:
這種情況下,系統在編譯block時,發現有個num變數,外部沒有用__block修飾,系統會在堆區中建立一個同名同類型的變數,在真正執行程式碼的時候,如果沒有對num進行修改的操作,那麼就會直接呼叫堆區中的num的值,這個值是在編譯的時候已經賦給堆區變數的,列印(簡單地說這個時候block內部與外部沒有任何的關係),當block執行完畢後,呼叫的num還是之前的棧區中建立的num
加”block”:
這個時候,程式在編譯block程式碼塊的時候,發現num是被__block修飾的,就不會上來就在堆區中建立num變數,而是在執行到這裡的時候才去按照外部的同名變數去在堆區中建立num,與此同時,會修改外部變數的地址,這個地址是堆區中num的地址,所以在最後列印num的地址,是指向堆區的,因而獲取的值也是堆區中num的值