web-dev-qa-db-ja.com

ブロック宣言構文リスト

Objective C(および実際にはC、私が推測する)のブロック構文は、悪名高いほど不整合です。ブロックを引数として渡すことは、ブロックをivarとして宣言することとは異なります。これは、typedefingブロックとは異なります。

すぐに参照できるように手元に置いておくことができるブロック宣言構文の包括的なリストはありますか?

275
Patrick Perini

ブロック宣言構文のリスト

全体を通して

  • 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)

言語機能のようです。

692
Patrick Perini

私は個人的にこのウェブサイトを使用するのが好きです( http://fuckingblocksyntax.com )。名前は、ブロック構文自体よりも覚えやすいです。

http://fuckingblocksyntax.com

間違った単語を含むURLをロードできない場合は、このミラーを使用できます。 http://goshdarnblocksyntax.com

fuckingblocksyntax website

80
psy

Typedef:

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

列をなして:

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

方法:

- (void)method:(void (^)(NSString *param))handler
39
Erik Aigner

Xcode 4スニペットライブラリには、変数としてブロックタイプ定義とインラインブロックのテンプレートが含まれています。また、オートコンプリート(typedefblockおよびinlineblock)を介して利用できます。

メソッドの引数としてのブロックについては、typedefを宣言してから、単純にそれを使用することをお勧めします。これにより、コードがはるかに読みやすくなります。

16
omz

振った後にサイコロの値を返すクラスのcompletionBlockを作成しました。

  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);
    }
    
11
Alex Cio
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;
6
benhi

Xcode 4.2に戻って作業する必要がある場合は、非ブロックプロパティの場合と同様に、プロパティとして宣言されたブロックを@synthesizeすることもできます。ブロック構文にあなたを投げさせないでください。

ブロックプロパティがこれである場合:

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

あなたの@synthesizeはこれです:

@property blockName;

乾杯。

3
Alex Zavatone