块声明语法列表


277

众所周知,Objective C(甚至我认为确实是C)中的块语法是不一致的。将块作为参数传递看起来与将块声明为ivars不同,后者看起来与typedefing块不同。

是否有可供我快速参考的块声明语法的完整列表?


9
块编程主题指南中的“声明和创建块”有什么问题?
jscs 2012年

使用块属性的简单说明: stackoverflow.com/a/20760583/294884
Fattie 2015年

Answers:


696

块声明语法列表

在整个过程中,让

  • return_type是对象/原始/等的类型。您想返回(通常是void
  • blockName 是您要创建的块的变量名
  • var_type是类型object / primitive / etc。您想作为参数传递(不带任何参数保留空白)
  • varName 是给定参数的变量名

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

块作为变量

可能是最常见的声明方式。

return_type (^blockName)(var_type) = ^return_type (var_type varName)
{
    // ...
};

块作为属性

就像将块声明为变量一样,但是有细微的差别。

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

块作为参数

注意,这与“块作为参数”不同;在这种情况下,您要声明一个需要块参数的方法。

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

块作为参数

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

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

匿名块

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

^return_type (var_type varName)
{
    //...
};

typedef

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

typedef return_type (^blockName)(var_type);

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

内联块

可以说这是对块的不太有用的利用,但是仍然可以占有一席之地。内联块是实例化后立即调用的匿名块。

^return_type (var_type varName)
{
    //...
}(var);

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

{
   //...
}

递归块

这使您可以从自身调用一个块,从而创建一个可在回调和GCD调用期间使用的循环。此实例化方法没有ARC中的保留周期。

__block return_type (^blockName)(var_type) = [^return_type (var_type varName)
{
    if (returnCondition)
    {
        blockName = nil;
        return;
    }

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

返回块

方法可以返回一个块,

- (return_type(^)(var_type))methodName
{
    // ...
}

和功能一样,如果有些奇怪的话。

return_type (^FunctionName())(var_type)
{
    // ...
}

补遗

如果我错过了任何事情,请在评论中让我知道,我将进行研究/添加。

哦,在Swift中...

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

这几乎就像是一种语言功能。


1
@pcperini很棒的清单!以及如何在变量声明(列表中的第一项)中使用基于类型定义的块定义?逻辑BlockType ^blockVar = Anonymous Block显示语法错误,也没有^ :(
esp

14
不知何故,我的大脑无法记住所有这些用于块声明的语法。我大概每周看一次这个答案。希望我能为此给您10票赞成票。
本·巴伦

36
我们需要一个StackOverflow名人堂来获得这样的答案。
bejonbee

1
我已经将其转换为Markdown,以供查看器进行打印。便利!gist.github.com/swizzlr/6268955
Swizzlr

20
我想我需要这个作为纹身。
Isaac Overacker 2013年


39

Typedef:

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

排队:

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

方法:

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

这个答案表明,它毕竟并没有那么复杂...只是3种不同的语法可以混合使用。
陈约瑟

4
接受的答案只是此答案的副本,带有不必要的膨胀。
Erik Aigner 2014年

16

Xcode 4片段库包含块typedef和内联块作为变量的模板。也可以通过自动完成功能(typedefblockinlineblock)使用它们。

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


11

我为一个类编写了一个completeBlock,该类将在摇动后返回骰子的值:

  1. 用returnType定义typedef(.h上面的@interface声明)

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

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

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
  4. 插入先前定义的方法.m文件并提交finishBlock@property之前定义

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
  5. 触发completionBlock传递预定义的variableType到它(不要忘记检查是否completionBlock存在)

    if( self.completeDiceRolling ){
        self.completeDiceRolling(self.dieValue);
    }

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;

一步一步描述整个过程会很好,如果您不熟悉ios,那么很难理解这些块……
Alex Cio

3

如果您需要在Xcode 4.2中工作,也可以@synthesize声明为属性的块,就像使用非块属性一样。不要让块语法丢掉你。

如果您的块属性是这样的:

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

然后,您的@synthesize是这样的:

@property blockName;

干杯。


嗨,您能不能再检查一下。我只是想跟着您.. @property blockName没有用。我认为应该是@synthesize blockName;?(用于合成块)
jeet.chanchawat

糟糕...等等,您已经(间接)提到它无法与xcode 7配合使用
。– jeet.chanchawat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.