iOS基礎 Block變數截獲(總結)

2021-10-18 02:22:49 字數 1601 閱讀 5332

nsinteger number = 30;

nsinteger(^block)(nsinteger) = ^nsinteger(nsinteger n);

num = 5;

nslog(@"%zd", block(10));

這裡輸出結果是 40,而不是 15,原因是對區域性變數 number 的截獲是 「值截獲」。在 block 裡面修改 number,是無效的,並且編譯會報錯。

nsmutablearray *testarray = [nsmutablearray arraywithobjects:@"zhang",@"li", nil];

void(^block)(void) = ^;

[testarray addobject:@"wang"];

testarray = nil;

block();

列印結果為 zhang, li, wang

區域性物件變數也是 「值截獲」,截獲的是值,而不是指標,在外部將其置為 nil,對 block 沒有影響。

static nsinteger number = 30;

nsinteger(^block)(nsinteger) = ^nsinteger(nsinteger n);

number = 5;

nslog(@"%zd", block(10));

輸出結果是 15,說明 number = 5 的修改是有效的,即是 「指標截獲」。

同時,在 block 裡修改變數 number ,也是有效的(如:在 block 裡面將 number 修改為 50,輸出結果為 60)。

用 clang 編譯一下

static nsinteger number3 = 100;

nsinteger number4 = 1000;

- (void)blocktest

; number = 50;

number2 = 5;

number3 = 500;

number4 = 5000;

number5 = 50000;

block();

}

輸出結果為 :10    5    500    5000    50000

編譯後

struct __block__blocktest_block_impl_0 

};

從 「&_nsconcretestackblock」 可以看出,這是乙個棧block。區域性變數被編譯成值形式,而靜態變數被編譯成指標形式,全域性變數並未截獲。而__block 修飾的變數也是以指標形式截獲的,並且生成了乙個新的物件:

struct __block_byref_number5_0 ;
對於區域性變數,如果需要在 block 內部進行賦值操作,需要給區域性變數新增__block 修飾符,而對於全域性變數、靜態變數是不需要新增__block 修飾符的。如果 block 內部訪問了 self 或者 self 的成員變數,block 會截獲 self。

Block 5 Block解析之截獲區域性變數值

源 int main int argc,const char argv val 2 fmt these values were changed.val d n blk return 0 將上面的源 用命令 clang rewrite objc main.c 轉換為c 如下 struct main b...

Block中是如何實現截獲自動變數值的呢?

我們都說block會捕獲 持有 它使用到的區域性變數的值,可是它是如何實現捕獲自動變數的值的呢?下面依然是使用一段 然後用clang進行轉換,來分析其過程。轉換前的main.m原始碼 import intmain int argc,const char ar a 20 blk return0 str...

iOS中Block介紹(一)基礎

block是c級別的語法和執行時特性。block比較類似c函式,但是block比之c函式,其靈活性體現在棧記憶體 堆記憶體的引用,我們甚至可以將乙個block作為引數傳給其他的函式或者block。先看乙個比較簡單的block例子 int multiplier 7 int myblock int in...