Block 是帶有自動變量捕獲的匿名函數,類似閉包。語法:^返回類型(參數列表) { 函數體 }。
| 變量類型 | 默認捕獲方式 | 加 __block 後 |
|---|---|---|
| 局部自動變量 | 值捕獲(const 拷貝),Block 內只讀 | 引用捕獲(共享存儲),可讀寫,修改對外可見 |
| 靜態局部變量 | 引用捕獲(地址),可讀寫 | 同默認,__block 無效果 |
| 全局變量 | 引用捕獲,可讀寫 | 同默認 |
| 常量字面量/對象 | 值捕獲(淺拷貝指針) | 引用捕獲變量指針,可修改指向 |
int a = 10;
void (^blk)() = ^{
// a = 20; // 編譯錯誤:捕獲為 const int
printf("%d", a); // 讀取 10
};
__block int b = 10;
void (^blk2)() = ^{
b = 20; // 允許修改
printf("%d", b); // 20
};
blk2();
printf("%d", b); // 20,外部也變了
static int s = 5;
void (^blk3)() = ^{ s = 6; }; // 合法,修改靜態變量
NSString *constStr = @"hello";
void (^blk4)() = ^{
// constStr = @"world"; // 錯誤:捕獲為 const 指針
};
__block NSString *blkStr = @"hello";
void (^blk5)() = ^{ blkStr = @"world"; }; // 合法,修改指向
__block 變量在堆上分配(或棧上但會隨 Block copy 移至堆),引用計數管理。Block_copy 或 ARC 下賦值給強引用)時,會 retain 捕獲的 __block 變量及對象指針。__weak 或 __block (MRC) 弱化 self。Block 內可定義與外部同名的局部變量,會遮蔽外部捕獲變量,外部變量在內部不可訪問。
__block。__block。