Block 是 C 語言級別的語法與運行機制,兼容 C/C++/Objective-C。除可執行代碼外,還攜帶綁定棧/堆內存的變量(狀態數據)。常作為回調傳遞,代碼與數據封裝在一起。
Block 內可直接使用外部作用域變量。但默認按值捕獲(拷貝):Block 內部持有該變量的一份只讀副本(`const`)。外部變量修改不影響 Block 內副本,Block 內也不能修改副本(編譯錯誤)。
int a = 10;
void (^blk)() = ^{
// a 在此處為 const int,不可修改
NSLog(@"%d", a); // 10
};
a = 20;
blk(); // 仍輸出 10,捕獲的是創建時的值
Block 內定義同名變量會遮蔽捕獲的外部變量。
給外部變量加 `__block`,Block 將捕獲其地址引用而非值拷貝。Block 內可修改,修改對外部可見;外部修改對 Block 可見。實現機制:`__block` 變量被包裝在一個結構體中,引用計數管理,隨 Block 在棧/堆間移動。
__block int a = 10;
void (^blk)() = ^{
a = 20; // 允許修改
NSLog(@"%d", a);
};
blk(); // 20
NSLog(@"%d", a); // 20,外部也被修改
| 變量類型 | 無 `__block` | 有 `__block` |
|---|---|---|
| 局部自動變量 | 值拷貝(只讀) | 地址引用(可讀寫) |
| 靜態/全局變量 | 地址引用(可讀寫) | 地址引用(可讀寫) |
| 常量對象指針 | 指針值拷貝(不可改指向) | 指針地址引用(可改指向) |