Accès à une variable d'instance iVar
de votre classe à l'intérieur d'un bloc est interprété par le compilateur comme self->iVar
. Par conséquent, le bloc capture self
qui n'est pas modifié.
Je suis sûr que le __block
fonctionne également avec dispatch_async
Il s'agit donc d'une erreur de documentation.
ADDED
L'exemple suivant montre comment une __block
peut être utilisée avec dispatch_async
:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
__block int total = 0;
printf("address of total: %p\n", &total);
// dispatch some (concurrent) blocks asynchronously:
dispatch_async(queue, ^{
OSAtomicAdd32(5, &total);
});
dispatch_async(queue, ^{
OSAtomicAdd32(7, &total);
});
// Wait for all blocks to complete:
dispatch_barrier_sync(queue, ^{ });
printf("address of total: %p\n", &total);
printf("total=%d\n", total);
Sortie :
address of total: 0x7fff5fbff8f0
address of total: 0x100108198
total=12
On peut voir que total
est copié de la pile au tas lorsque les blocs sont exécutés.
ADDED
Je viens de trouver ceci dans le Guide de programmation des blocs . Il explique pourquoi il n'y a aucun problème à utiliser __block
variables avec des blocs asynchrones.
Les variables __block vivent dans un stockage partagé entre la portée lexicale de la variable et tous les blocs et copies de blocs déclarés ou créés dans la portée lexicale de la variable. créés dans la portée lexicale de la variable. Ainsi, le stockage survivra à la destruction de la trame de la pile si des copies des blocs déclarés à l'intérieur du cadre survivent au-delà de la fin du cadre (par par exemple, en étant mis en file d'attente quelque part pour une exécution ultérieure). Plusieurs blocs blocs dans un champ lexical donné peuvent utiliser simultanément une variable partagée.
En guise d'optimisation, le stockage en bloc commence sur le pile, tout comme les blocs eux-mêmes. Si le bloc est copié en utilisant Block_copy (ou en Objective-C lorsque le bloc est envoyé en copie), les variables sont copiées sur le tas. Ainsi, l'adresse d'une variable __block peut changer au fil du temps.