关于C#:块声明语法列表

Block Declaration Syntax List

目标C中的块语法(实际上是C,我猜想)是出了名的不协调。将块作为参数传递与将块声明为ivars不同,后者看起来与typedefing块不同。

是否有一个完整的块声明语法列表,我可以随身携带以便快速参考?


块声明语法列表

贯穿,让

  • return_type是您想要返回的对象/原语类型(通常是void)
  • blockName是您正在创建的块的变量名
  • var_type是类型object/primitive/etc。您想作为参数传递(没有参数保留为空)
  • varName是给定参数的变量名

记住,您可以创建任意多的参数。

块作为变量

可能是申报中最常见的。

1
2
3
4
return_type (^blockName)(var_type) = ^return_type (var_type varName)
{
    // ...
};

块作为属性

很像将块声明为变量,尽管有细微的不同。

1
@property (copy) return_type (^blockName) (var_type);

块作为参数

请注意,这与"块作为参数"不同;在本例中,您要声明一个需要块参数的方法。

1
- (void)yourMethod:(return_type (^)(var_type))blockName;

块作为参数

注意,这与"块作为参数"不同;在本例中,您调用的方法需要一个带有匿名块的块参数。如果已经声明了块变量,则只需将变量名作为参数传递即可。

1
2
3
4
[someObject doSomethingWithBlock: ^return_type (var_type varName)
{
    //...
}];

匿名块

这在功能上是一个匿名块,但是将块分配给变量的语法只是将变量设置为一个匿名块。

1
2
3
4
^return_type (var_type varName)
{
    //...
};

typedef区块

这允许您设置一个短名称,可以像在块声明期间引用任何其他类名一样被引用。

1
typedef return_type (^blockName)(var_type);

为了以后使用blockName而不是标准块声明语法,只需替换即可。

内联块

这可以说是块的一种不太有用的利用,但可能仍然有它的位置。内联块是在实例化后立即调用的匿名块。

1
2
3
4
^return_type (var_type varName)
{
    //...
}(var);

内联块主要用于范围偏移,大致相当于简单的括号分隔的代码块。

1
2
3
{
   //...
}

递归块

这允许您从自身调用一个块,从而创建一个可在回调和GCD调用期间使用的循环。这种实例化方法在弧中不存在保留循环。

1
2
3
4
5
6
7
8
9
10
11
__block return_type (^blockName)(var_type) = [^return_type (var_type varName)
{
    if (returnCondition)
    {
        blockName = nil;
        return;
    }

    // ...
} copy];
blockName(varValue);

返回块

方法可以返回块,

1
2
3
4
- (return_type(^)(var_type))methodName
{
    // ...
}

函数也可以,如果有点奇怪。

1
2
3
4
return_type (^FunctionName())(var_type)
{
    // ...
}

补遗

如果我遗漏了什么,请在评论中告诉我,我会研究/添加它们。

哦,而且很快…

1
blockName = (varName: var_type) -> (return_type)

这就像是一个语言特性。


我个人喜欢使用这个网站(http://fuckingblocksyntax.com)。名称比块语法本身更容易记住:

http://该死的blocksyntax.com

如果不能加载包含坏词的URL,可以使用此镜像:http://goshdarnblocksyntax.com

fuckingblocksyntax website


Typedef:

1
typedef void (^block)(NSString *arg);

内联:

1
2
3
void (^block)(NSString *) = ^(NSString *param) {
  // do something....
};

方法:

1
- (void)method:(void (^)(NSString *param))handler


xcode 4代码段库包含块typedef和内联块作为变量的模板。它们也可以通过自动完成(typedefblockinlineblock获得。

对于作为方法参数的块,我建议声明一个typedef,然后简单地使用它。它使代码更容易阅读。


我为一个类编写了一个completionBlock,它将在骰子被摇动后返回其值:

  • 使用返回类型定义typedef(.h高于@interface声明)

    1
    typedef void (^CompleteDiceRolling)(NSInteger diceValue);
  • 为块定义一个@property(.h)

    1
    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
  • finishBlock定义方法(.h)

    1
    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
  • .m文件中插入以前定义的方法,并将finishBlock提交到之前定义的@property

    1
    2
    3
    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
  • 要触发completionBlock,请将预定义的变量类型传递给它。(别忘了检查completionBlock是否存在)

    1
    2
    3
    if( self.completeDiceRolling ){
        self.completeDiceRolling(self.dieValue);
    }

  • 1
    2
    3
    4
    5
    6
    7
    typedef void (^OkBtnBlock)(id data);
    typedef void (^CancelBtnBlock)();

    @property (nonatomic, strong) OkBtnBlock okBtnBlock;
    @property (nonatomic, strong) CancelBtnBlock cancelBtnBlock;

    + (void)foo:(OkBtnBlock)okBtn andCancel:(CancelBtnBlock)btnCancel;


    如果您需要在Xcode4.2中工作,您还可以@synthesis声明为属性的块,就像使用非块属性一样。不要让块语法抛弃您。

    如果块属性为:

    1
    @property (copy) return_type (^blockName) (var_type);

    那么你的@synthesis是:

    1
    @property blockName;

    干杯。