什么是block:帶有自動變量(局部變量)的匿名函數(shù)。
1、 匿名函數(shù):顧名思義不帶有名稱的函數(shù)。C語言的標準不允許存在這樣的函數(shù)。
// 聲明名稱為func的函數(shù)
int func (int cout);
// 正常的使用,使用函數(shù)該函數(shù)的名稱func調(diào)用
int result = func(10);
// 使用函數(shù)指針代替函數(shù),但使用函數(shù)指針也仍然需要知道函數(shù)的名稱
int(*funcptr)(int) = &func;
// 使用函數(shù)指針調(diào)用
result = (*funcptr)(10);
// 而通過使用Block,源代碼中就能夠使用匿名函數(shù),即不帶名稱的函數(shù)
2、 帶有自動變量的值在block中表現(xiàn)為“截取自動變量的值”。
int num = 123;
const char *fmt = "num = %d\n";
void(^block)(void) = ^{
printf(fmt,num);
};
num = 456;
fmt = "These values were changed. num = %@\n";
block();
// 打印 num = 123
Block語法的表達式使用的是之前聲明的自動變量fmt和num。Block中,Block表達式截獲所使用的自動變量的值,即保存該自動變量的瞬間值。因為Block表達式保存了自動變量的值,所以在執(zhí)行Block語法后,即使改寫B(tài)lock中使用的自動變量的值也不會影響B(tài)lock執(zhí)行時自動變量的值。
block語法: ^ 返回值類型 參數(shù)列表 表達式
^void(int num) {
};
^int(int num) {
return num;
};
1、其中返回值的類型可以省略
^(int num) {
return num;
};
2、如果不使用參數(shù),參數(shù)列表也可以省略。
^ {
printf("block\n");
};
Block類型變量
1、定義: 返回值類型(^blcok變量名稱)(參數(shù)列表)
int(^block)(int) = ^(int count) {
return count + 1;
};
block(2);
2、block變量與一般的C語言變量完全相同,可作為一下用途使用:
1、自動變量(局部變量)
2、函數(shù)參數(shù)
3、靜態(tài)變量
4、靜態(tài)全局變量
5、全局變量
3、使用typedef定義Block類型變量
typedef int (^Block_t) (int);
Block_t block = ^(int count) {
return count + 1;
};
block(2);
__block修飾符
1、自動變量的截獲只能保存執(zhí)行Block語法瞬間的值。保存后就不能改寫該值。如果修改改寫截取的自動變量值,會產(chǎn)生編譯錯誤。
2、使用__block修飾符修飾的自動變量可在Block中賦值,該變量稱為__block變量。
__block int num = 123;
void(^block)(void) = ^{
num = 456;
};
block();
printf("num = %d\n",num);
3、對于截獲的Objective-C對象:
賦值給截獲的自動變量的操作會產(chǎn)生編譯錯誤。
id array = [NSMutableArray array];
void(^block)(void) = ^{
array = [NSMutableArray array]; //這樣是不允許的
};
使用截獲的值不會有任何問題。
id array = [NSMutableArray array];
void(^block)(void) = ^{
[array addObject:[[NSObject alloc] init]];
};
對于需要對被截取的Objective-C對象自動變量賦值,可使用__block修飾。
__block id array = [NSMutableArray array];
void(^block)(void) = ^{
array = [NSMutableArray array];
};
待續(xù)
參考
《Objective-C高級編程》