web-dev-qa-db-fra.com

Stockage de blocs dans un tableau

Dans Objective-C, je sais que les blocs sont considérés comme des objets, donc je me demandais s'il était possible de les stocker dans un tableau. Cela soulève la question: les blocs sont-ils des objets de première classe ou sont-ils simplement traités comme des objets pour les faire passer entre les objets? S'ils sont des objets de première classe, ne devraient-ils pas être stockés dans des tableaux?

50
noizetoys

EDIT: Sans entrer dans trop de détails, sous ARC, vous pouvez maintenant ajouter des blocs aux collections comme n'importe quel autre objet (voir discussion).

J'ai laissé la réponse originale intacte ci-dessous, car elle contient des détails techniques intéressants.


Cela pose la question: les blocs sont-ils des objets de première classe ou sont-ils simplement traités comme des objets dans le but de les passer d'un objet à l'autre? S'ils sont des objets de première classe, ne devraient-ils pas être stockés dans des tableaux?

Les blocs sont des objets Objective-C qui se comportent très bien comme tous les autres NSObject, avec quelques différences clés:

  • Les blocs sont toujours générés par le compilateur. Ils sont effectivement "allocés/initiés" au moment de l'exécution lorsque l'exécution passe sur la déclaration des blocs.

  • Les blocs sont initialement créés sur la pile. Block_copy () ou la méthode copy doit être utilisée pour déplacer le bloc vers le tas si le bloc doit survivre à la portée actuelle (voir le point ARC ci-dessous).

  • Les blocs n'ont pas vraiment d'API appelable au-delà de la gestion de la mémoire.

  • Pour placer un bloc dans une collection, il doit d'abord être copié Toujours. Y compris sous ARC. (Voir les commentaires.) Si vous ne le faites pas, il y a un risque que le bloc alloué par la pile soit autoreleased et que votre application plante plus tard.

  • La copie d'un bloc basé sur la pile copiera également tout l'état capturé. Si vous effectuez plusieurs copies d'un bloc, il est plus efficace de le copier une fois, puis de copier la copie (car la copie de la copie fait simplement augmenter le nombre de retenues car les blocs sont immuables).

  • Sous ARC, le retour d'un bloc à partir d'une méthode ou d'une fonction "fonctionne tout simplement"; il sera automatiquement copié dans le tas et le retour sera effectivement un bloc libéré automatiquement (le compilateur peut optimiser la libération automatique dans certaines circonstances). Même avec ARC, vous devez toujours copier le bloc avant de le coller dans une collection.

J'ai écrit quelques articles de blog fournissant à la fois un introduction aux blocs et certains trucs et astuces . Vous pourriez les trouver intéressants.

Et, oui, les ajouter aux dictionnaires est très utile. J'ai écrit quelques bits de code où j'ai déposé des blocs dans les dictionnaires en tant que gestionnaires de commandes où la clé était le nom de la commande. Très utile.

90
bbum

Oui, les blocs sont en effet des objets, et vous pouvez les mettre en tableaux:

NSMutableArray *arr = [NSMutableArray new];
[arr addObject:^(){NSLog(@"my block");}];
void (^ myblock)() = [arr objectAtIndex:0];
myblock();

cela mettra le "mon bloc" dans la console.

39
Eduardo Scoz