Que signifie exactement le __block
mot - clé dans Objective-C? Je sais que cela vous permet de modifier des variables dans des blocs, mais j'aimerais savoir ...
- Que dit-il exactement au compilateur?
- Cela fait-il autre chose?
- Si c'est tout ce qu'il fait, pourquoi est-il nécessaire en premier lieu?
- Est-ce dans les documents n'importe où? (Je ne le trouve pas).
objective-c
ios
objective-c-blocks
mjisrawi
la source
la source
__block
du tout.__block
devraient se traduire en Swift: «Les fermetures [dans Swift] ont une sémantique de capture similaire à celle des blocs [dans Objective-C] mais diffèrent d'une manière clé: les variables sont mutables plutôt que copiées. En d'autres termes, le comportement de __block dans Objective-C est le comportement par défaut des variables dans Swift. » Tiré du livre d'Apple: Utilisation de Swift avec Cocoa et Objective-C (Swift 2.2).Réponses:
Il indique au compilateur que toute variable marquée par lui doit être traitée d'une manière spéciale lorsqu'elle est utilisée à l'intérieur d'un bloc. Normalement, les variables et leur contenu qui sont également utilisés dans les blocs sont copiés, ainsi toute modification apportée à ces variables n'apparaît pas en dehors du bloc. Quand ils sont marqués avec
__block
, les modifications effectuées à l'intérieur du bloc sont également visibles à l'extérieur de celui-ci.Pour un exemple et plus d'informations, consultez Le type de stockage __block dans les rubriques de programmation des blocs d'Apple .
L'exemple important est celui-ci:
Dans cet exemple, les deux
localCounter
etlocalCharacter
sont modifiés avant l'appel du bloc. Cependant, à l'intérieur du bloc, seule la modification àlocalCharacter
serait visible, grâce au__block
mot - clé. Inversement, le bloc peut être modifiélocalCharacter
et cette modification est visible à l'extérieur du bloc.la source
localCounter
, mais il modifielocalCharacter
. Faites également attention à la valeurlocalCounter
du bloc: c'est 42, même si la variable est augmentée avant l'appel du bloc mais après la création du bloc (c'est à ce moment que la valeur a été "capturée").@bbum couvre les blocs en profondeur dans un article de blog et touche au type de stockage __block.
En ce qui concerne les cas d'utilisation, vous constaterez qu'il
__block
est parfois utilisé pour éviter les cycles de conservation car il ne conserve pas l'argument. Un exemple courant est d'utiliser soi-même.la source
__weak
suffirait-il également dans ce cas précis? C'est peut-être un peu plus clair ...Normalement, lorsque vous n'utilisez pas __block, le bloc copiera (conservera) la variable, donc même si vous modifiez la variable, le bloc a accès à l'ancien objet.
Dans ces 2 cas, vous avez besoin de __block:
1.Si vous souhaitez modifier la variable à l'intérieur du bloc et vous attendre à ce qu'elle soit visible à l'extérieur:
2.Si vous souhaitez modifier la variable après avoir déclaré le bloc et que vous vous attendez à ce que le bloc voit le changement:
la source
__block est un qualificatif de stockage qui peut être utilisé de deux manières:
Marque qu'une variable vit dans un stockage partagé entre la portée lexicale de la variable d'origine et tous les blocs déclarés dans cette portée. Et clang générera une structure pour représenter cette variable et utilisera cette structure par référence (et non par valeur).
Dans MRC, __block peut être utilisé pour éviter de conserver les variables d'objet qu'un bloc capture. Attention à ce que cela ne fonctionne pas pour ARC. Dans ARC, vous devez utiliser __weak à la place.
Vous pouvez vous référer à Apple Doc pour des informations détaillées.
la source
__block
est un type de stockage utilisé pour rendre les variables de portée mutables, plus franchement si vous déclarez une variable avec ce spécificateur, sa référence sera transmise aux blocs et non à une copie en lecture seule pour plus de détails, voir Programmation des blocs dans iOSla source
J'espère que cela vous aidera
supposons que nous ayons un code comme:
cela donnera une erreur comme "la variable n'est pas assignable" car la variable de pile à l'intérieur du bloc est par défaut immuable.
l'ajout de __block (modificateur de stockage) avant sa déclaration le rend modifiable à l'intérieur du bloc, c'est-à-dire
__block int stackVariable=1;
la source
De la spécification de langue de bloc :
Pour plus d'informations sur la compilation d'une variable __block, reportez-vous à la Spécification d'implémentation de bloc , section 2.3.
la source
Cela signifie que la variable dont il s'agit d'un préfixe est disponible pour être utilisée dans un bloc.
la source