1. 程式人生 > >關於block中呼叫外部基本資料型別變數問題

關於block中呼叫外部基本資料型別變數問題

先看兩種方式的程式碼:

- (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的值