译自:Declaring and Creating Blocks
1. 声明Block引用
block变量保留了对blocks的引用。声明block同声明一个函数指针的语法相似,只需要使用 ^ 替换为 *,block类型能够同C类型系统中其他类型交互,下面的都是有效的block变量声明:
void (^blockReturningVoidWithVoidArgument)(void);
int (^blockReturningIntWithIntAndCharArguments)(int, char);
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
Block也支持可变参数(...), 不带任何参数的block必须在参数列表中指定 void 类型。Blocks是被设计成类型安全的,它通过给编译器一整套的元数据使用来确认blocks的使用,传递给blocks的参数,以及返回值的赋值。你可以将block引用转化为其他类型的指针,反之亦然。但是你不能通过指针解引用操作符(*)解引用一个block引用,因为在编译时不能计算出block的大小。
可以为block创建一个类型。在多个地方使用block时为其指定一个标识,这是一个好的习惯。
typedef float (^MyBlockType)(float, float);
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;
2. 创建Block
使用 ^ 操作符来指定block表达式的开始,紧跟着它的可能是包含在()中的参数列表,block的函数体包含在 {} 中,下面的例子定义了一个简单的block并且将它赋值给提前声明的变量(oneForm)
int (^oneFrom)(int);
oneFrom = ^(int anInt) {
return anInt - 1;
};
如果你没有显示声明block表达式的返回类型,它能够从blocks的上下文中自动推测出来。如果能够推测出返回类型并且参数列表是 void ,你可以忽略 (void) 参数列表,当有多个返回语句时,它们的返回类型必须完全相同,必要的时候可使用类型转化。
3. 全局的Blocks
At a file level, you can use a block as a global literal:
#import <stdio.h>
int GlobalInt = 0;
int (^getGlobalInt)(void) = ^{ return GlobalInt; };
在上例中, ^ 操作符后没有跟这参数列表,因为block的返回类型可以推测,并且参数列表为空,可以直接省去。