Block 語(yǔ)法
Block字面量
^ [return type] (argument list) {
expressions
}
可以省略return type
^ (argument list) {
expressions
}
當(dāng)return type和參數(shù)都為空時(shí)
^void (void) {
printf("Blocks\n");
}
^{
printf("Blocks\n");
}
Block類型變量
Function變量
int func(int count)
{
return count + 1;
}
int (*funcptr)(int) = &func;
Block 變量
int (^blk)(int);
和其它C語(yǔ)言變量一樣,Block變量能作為:
- Automatic variables, atuo變量
- Function arguments,函數(shù)參數(shù)
- Static variables,靜態(tài)變量
- Static global variables,全局靜態(tài)變量
- Global variables,全局變量
int (^blk)(int) = ^(int count) { return count + 1;};
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk1;
Block類型可以作為函數(shù)為參數(shù)
void func(int (^blk)(int))
{
}
Block也可以作為函數(shù)的返回值
int (^func()(int)) {
return ^(int count){return count + 1;};
}
用typedef簡(jiǎn)化Block類型變量的使用
typedef int (^blk_t)(int);
/* original
void func(int (^blk)(int)){...}
*/
void func(blk_t blk){...}
/* original
int (^func()(int)){...}
*/
blk_t func(){...}
執(zhí)行Block
// execute func
int result = (*funcptr)(10);
// execute block
int result = blk(10);
int func(blk_t blk, int rate) {
return blk(rate);
}
Block指針
typedef int (^blk_t)(int);
blk_t blk = ^(int count){return count + 1;};
blk_t *blkptr = &blk;
(*blkptr)(10);
獲取 automatic變量
當(dāng) automatic 變量被Block獲取時(shí), 該變量在Block中是只讀的 read-only. 你不能修改它.
但是如是獲取的automatic變量是Objective-C對(duì)象呢?看下面代碼:
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];
};
在C語(yǔ)言層上,Block捕獲的是NSMutableArray對(duì)象的結(jié)構(gòu)體的指針。你可以修改該指針指向的對(duì)象的內(nèi)容,但不能修改這個(gè)指針本身,否則編譯器會(huì)報(bào)錯(cuò)(下面代碼)。
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc] init];
};
為了能夠修改捕獲的auto變量, 你需要用__block來修飾你的auto 變量。
__block id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc] init];
};
另外,當(dāng)使用C數(shù)組時(shí),請(qǐng)使用數(shù)組的指針。
const char text[] = "hello";
void (^blk)(void) = ^{
printf("%c\n", text[2]);
};
上面代碼看上去,沒任何問題,事實(shí)上,會(huì)產(chǎn)生編譯錯(cuò)誤:
error: cannot refer to declaration with an array type inside block printf("%c\n", text[2]);
^
note: declared here
const char text[] = "hello";
^
就是說不能在Block中使用數(shù)組,用數(shù)組的指針代替:
const char *text = "hello";
void (^blk)(void) = ^{
printf("%c\n", text[2]);
};
這樣就沒問題了。