Block 的语法

一直以来还是有不少人不满block语法,甚至有人成立了一个叫做fuckingblocksyntax.com的网站。这个网站的网域名称不怎么优雅,不过里头倒是清楚整理了我们应该如何定义block。

将block 宣告成变数(local variable)的语法是:

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

定义成Objective-C property 的语法是:

@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);

定义成method 的参数(method parameter)的语法是:

- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;

在执行某个需要传入block 当做参数的method 的时候,则是用这以下方式调用。这也是绝大多数用block 当做callback 的处理方式:

[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];

把一种block 定义成typedef:

typedef returnType (^TypeName)(parameterTypes);

TypeName blockName = ^returnType(parameters) {...};

Block 也可以当成C function 的参数或是回传结果的类型,但是,在这种状况下,我们不能够直接使用returnType (^)(parameterTypes) 这种语法,必须要先定义成typedef 才行。也就是说,这样会被当成不合法:

(void (^)(void)) test((void (^)(void)) block) {
    return block;
}

但可以写成这样:

typedef void (^TestBlock)(void);
TestBlock test(TestBlock block) {
    return block;
}

虽然C function 的参数不能够使用returnType (^)(parameterTypes) 语法,但是一个block 倒是可以使用这种语法撰写输入与回传值的类型,但其实在这种状况下,还是比较建议使用typedef 定义。比方说,我们现在要定义一个block,这个block 会回传另外一个类型为int(^)(void) 的block,就会写成这样:

int (^(^counter_maker)(void))(void) = ^ {
    __block int x = 0;
    return ^ {
        return ++x;
    };
};

可读性实在非常差。不如写成这样:

typedef int (^CounterMakerBlock)(void);
CounterMakerBlock (^counter_maker)(void) = ^ {
    __block int x = 0;
    return ^ {
        return ++x;
    };
};

results matching ""

    No results matching ""