web-dev-qa-db-fra.com

Liste de syntaxe de déclaration de bloc

La syntaxe de bloc dans Objective C (et même C, je présume) est notoirement incongrue. Passer des blocs en tant qu'arguments est différent de la déclaration de blocs en tant qu'ivars, ce qui est différent de celui de typedefing.

Existe-t-il une liste complète de syntaxe de déclaration de bloc que je pourrais garder sous la main pour une référence rapide?

276
Patrick Perini

Liste des syntaxes de déclaration de bloc

Tout au long, laisser

  • return_type soit le type d'objet/primitive/etc. vous souhaitez retourner (généralement void)
  • blockName être le nom de la variable du bloc que vous créez
  • var_type soit le type objet/primitive/etc. vous souhaitez passer en argument (laissez vide pour aucun paramètre)
  • varName soit le nom de la variable du paramètre donné

Et rappelez-vous que vous pouvez créer autant de paramètres que vous le souhaitez.

Blocs en tant que variables

Peut-être le plus commun pour de la déclaration.

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

Blocs en tant que propriétés

Cela ressemble beaucoup à la déclaration de blocs en tant que variables, même si elles sont légèrement différentes.

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

Blocs en paramètres

Notez que ceci est distinct de "Blocks as Arguments"; dans ce cas, vous déclarez une méthode qui veut un argument de bloc.

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

Blocs comme arguments

Notez que ceci est distinct de "Blocks as Parameters"; dans ce cas, vous appelez une méthode qui souhaite un argument de bloc avec un bloc anonyme. Si vous avez déjà déclaré une variable de bloc, il suffit de passer le nom de la variable en tant qu'argument.

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

Bloc anonyme

Il s'agit fonctionnellement d'un bloc anonyme. Cependant, la syntaxe pour affecter des blocs aux variables consiste simplement à définir la variable sur un bloc anonyme.

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

typedef Block

Cela vous permet de définir un nom abrégé pouvant être référencé comme tout autre nom de classe lors de la déclaration de blocs.

typedef return_type (^blockName)(var_type);

Pour utiliser ensuite plus tard blockName à la place de la syntaxe de déclaration de bloc standard, remplacez simplement.

Bloc en ligne

Ceci est sans doute une utilisation moins utile des blocs, mais peut néanmoins avoir sa place. Un bloc en ligne est un bloc anonyme appelé immédiatement après l'instanciation.

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

Les blocs en ligne sont principalement utiles pour la compensation de périmètre et sont à peu près équivalents à de simples morceaux de code délimités par des accolades.

{
   //...
}

Blocs récursifs

Cela vous permet d'appeler un bloc depuis lui-même, créant ainsi une boucle pouvant être utilisée lors des rappels et des appels GCD. Cette méthode d'instanciation est libre de cycles de conservation dans ARC.

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

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

Renvoi de blocs

Une méthode peut retourner un bloc,

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

comme peut le faire une fonction, même si c'est un peu étrange.

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

Addendums

Si j'ai oublié quelque chose, merci de me le faire savoir dans les commentaires et je les rechercherai/les ajouterai.

Oh, et à Swift ...

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

C'est presque comme si c'était une fonctionnalité linguistique.

693
Patrick Perini

Personnellement, j'aime utiliser ce site Web ( http://fuckingblocksyntax.com ). Le nom est plus facile à retenir que la syntaxe de bloc elle-même:

http://fuckingblocksyntax.com

et si vous ne pouvez pas charger les URL contenant des mots incorrects, vous pouvez utiliser ce miroir: http://goshdarnblocksyntax.com

fuckingblocksyntax website

80
psy

Typedef:

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

En ligne:

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

Méthode:

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

La bibliothèque de fragments Xcode 4 contient des modèles de variables de type et de blocs en ligne. Ils sont également disponibles en complétion automatique (typedefblock et inlineblock).

Pour les blocs en tant qu'arguments aux méthodes, je vous conseillerais de déclarer un typedef et de l'utiliser simplement. Cela rend le code beaucoup plus facile à lire.

16
omz

J'ai écrit pour la classe d'achèvement un verrou qui retournera les valeurs d'un dé après leur agitation:

  1. Définir typedef avec returnType (.h au-dessus de @interface déclaration)

    typedef void (^CompleteDiceRolling)(NSInteger diceValue);
    
  2. Définir un @property pour le bloc (.h)

    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
    
  3. Définir une méthode avec finishBlock (.h)

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
    
  4. Insérer la méthode précédemment définie dans le fichier .m et valider finishBlock dans @property défini avant

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
    
  5. Pour déclencher completionBlock, passez-y le type de variable prédéfini (n'oubliez pas de vérifier si le completionBlock existe)

    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

Si vous avez besoin de travailler dans Xcode 4.2, vous pouvez également @ synthétiser un bloc déclaré en tant que propriété, comme vous le feriez avec une propriété non bloquante. Ne laissez pas la syntaxe de bloc vous jeter.

Si votre propriété de bloc est la suivante:

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

Ensuite, votre @ synthèse est la suivante:

@property blockName;

À votre santé.

3
Alex Zavatone