Avec ARC, je ne peux plus lancer CGColorRef
de casting id
. J'ai appris que je devais faire un casting ponté. Selon les documents de Clang :
Une distribution pontée est une distribution de style C annotée avec l'un des trois mots clés suivants:
(__bridge T) op
convertit l'opérande en type de destinationT
. SiT
est un type de pointeur d'objet pouvant être conservé, alorsop
doit avoir un type de pointeur non conservable. SiT
est un type pointeur non conservable, alors op doit avoir un type pointeur objet conservable. Sinon, le plâtre est mal formé. Il n'y a pas de transfert de propriété et ARC n'insère aucune opération de conservation.
(__bridge_retained T) op
convertit l'opérande, qui doit avoir un type de pointeur d'objet conservable, en type de destination, qui doit être un type de pointeur non conservable. ARC conserve la valeur, sous réserve des optimisations habituelles sur les valeurs locales, et le destinataire est responsable de l'équilibrage de ce +1.
(__bridge_transfer T) op
convertit l'opérande, qui doit avoir un type de pointeur non conservable, en type de destination, qui doit être un type de pointeur d'objet conservable. ARC publiera la valeur à la fin de l'expression complète englobante, sous réserve des optimisations habituelles sur les valeurs locales.Ces moulages sont nécessaires pour transférer des objets dans et hors du contrôle ARC; voir la justification dans la section sur la conversion des pointeurs d'objets conservables.
Utiliser un
__bridge_retained
ou un__bridge_transfer
moulage uniquement pour convaincre l'ARC d'émettre une retenue ou une libération déséquilibrée, respectivement, est une mauvaise forme.
Dans quel genre de situations utiliserais-je chacun?
Par exemple, CAGradientLayer
a une colors
propriété qui accepte un tableau de CGColorRef
s. Je suppose que je devrais utiliser __brige
ici, mais exactement pourquoi je devrais (ou ne devrais pas) n'est pas clair.
Réponses:
Je reconnais que la description prête à confusion. Puisque je viens de les saisir, je vais essayer de résumer:
(__bridge_transfer <NSType>) op
ou bienCFBridgingRelease(op)
est utilisé pour consommer un compte de rétention d'unCFTypeRef
moment en le transférant vers ARC. Cela pourrait également être représenté parid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
ou bienCFBridgingRetain(op)
est utilisé pour remettre unNSObject
terrain aux FC tout en lui donnant un compte de retenue de +1. Vous devez gérer un queCFTypeRef
vous créez de cette manière de la même manière que vous géreriez un résultatCFStringCreateCopy()
. Cela pourrait également être représenté parCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
jette juste entre pointeur-terre et Objective-C objet-terre. Si vous n'avez pas envie d'utiliser les conversions ci-dessus, utilisez celle-ci.C'est peut-être utile. Moi-même, je préfère
CFBridging…
un peu les macros aux plâtres simples.la source
J'ai trouvé une autre explication dans la documentation iOS que je pense est plus facile à comprendre:
__bridge
transfère un pointeur entre Objective-C et Core Foundation sans transfert de propriété.__bridge_retained (CFBridgingRetain)
jette un pointeur Objective-C vers un pointeur Core Foundation et vous transfère également la propriété.Vous êtes responsable d'appeler CFRelease ou une fonction associée pour renoncer à la propriété de l'objet.
__bridge_transfer (CFBridgingRelease)
déplace un pointeur non-Objective-C vers Objective-C et transfère également la propriété à l'ARC.ARC est responsable de renoncer à la propriété de l'objet.
Source: Types pontés sans frais
la source
Dans ce cas précis, si vous êtes sur iOS, Apple recommande d'utiliser UIColor et sa
-CGColor
méthode pour renvoyer le CGColorRef dans lecolors
NSArray. Dans les notes de mise à jour de la transition vers ARC , sous la section «Le compilateur gère les objets CF renvoyés par les méthodes Cocoa», il est indiqué que l'utilisation d'une méthode comme celle-CGColor
qui renvoie un objet Core Foundation sera automatiquement gérée correctement par le compilateur.Ainsi, ils suggèrent d'utiliser un code comme celui-ci:
Notez que pour le moment, l'exemple de code d'Apple ne contient pas le cast (id) que j'ai ci-dessus, ce qui est toujours nécessaire pour éviter une erreur du compilateur.
la source