165 votes

ARC et cast ponté

À l'ARC, je ne peux plus lancer de CGColorRef de id. J'ai appris que j'ai besoin de faire une passerelle en fonte. Selon clang docs:

Un ponté cast est un style C cast annoté avec l'un des trois mots-clés:

(__bridge T) op convertit l'opérande de destination type de T. Si T est un retainable objet de type pointeur, puis l'op doit avoir un non retainable type de pointeur. Si T est un non-retainable de type pointeur, ensuite, l'op doit avoir un retainable objet de type pointeur. Sinon le casting est mal formé. Il n'y a pas de transfert de propriété, et de l'ARC insère pas conserver opérations.

(__bridge_retained T) op convertit l'opérande, qui doit avoir retainable objet de type pointeur, pour le type de destination, qui doit être un non-retainable type de pointeur. ARC conserve la valeur, sous réserve de l' d'habitude les optimisations sur les valeurs locales, et que le destinataire est responsable pour l'équilibrage de +1.

(__bridge_transfer T) op convertit l'opérande, qui doit avoir non retainable de type pointeur, pour le type de destination, qui doit être une retainable objet de type pointeur. L'ARC va dégager de la valeur à la fin de la enfermant plein d'expression, sous réserve de l'habituel optimisations sur les valeurs locales.

Ces distributions sont nécessaires afin de transférer des objets dans et hors de Le contrôle de l'ARC; voir la justification dans la section sur la conversion de retainable pointeurs d'objet.

À l'aide d'un __pont_conservés ou __pont_transfert cast purement pour convaincre ARC d'émettre un déséquilibre de la conserver ou de la libération, respectivement, est pauvre forme.

Dans ce genre de situations devrais-je utiliser?

Par exemple, CAGradientLayer a colors de la propriété qui accepte un tableau d' CGColorRefs. Ma conjecture est que je devrais utiliser __brige ici, mais exactement pourquoi je devrait (ou ne devrait pas) n'est pas claire.

215voto

monkeydom Points 2148

Je suis d'accord que la description est source de confusion. Depuis que j'ai juste saisi, je vais essayer de résumer:

  • (__bridge_transfer <NSType>) op ou alternativement CFBridgingRelease(op) est utilisé pour consommer conserver-le comte de CFTypeRef pendant le transfert à l'ARC. Cela pourrait aussi être représenté par id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op ou alternativement CFBridgingRetain(op) est utilisé à la main un NSObject plus de CF-terre tout en lui donnant un +1 conserver le comte. Vous devez gérer un CFTypeRef vous créer de cette façon est la même que pour gérer une suite de CFStringCreateCopy(). Cela pourrait aussi être représenté par CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridge seulement jette entre le pointeur de la terre et de l'Objective-C objet-terre. Si vous n'avez pas d'inclination à utiliser les conversions ci-dessus, utilisez-la.

C'est peut-être utile. Moi, je préfère l' CFBridging… macros tout à fait un peu au-dessus de la plaine de moulages.

55voto

gregschlom Points 1824

J'ai trouvé une autre explication dans l'iOS de la documentation qui, je pense, est plus facile à comprendre:

  • __bridge des transferts d'un pointeur entre Objective-C et le Fondement de Base avec aucun transfert de propriété.

  • __bridge_retained jette un Objectif-C pointeur vers un Fondement de Base de pointeur et aussi des transferts de propriété pour vous.

    Vous êtes responsable pour l'appel de CFRelease ou une fonction liée à renoncer à la propriété de l'objet.

  • __bridge_transfer se déplace d'une non-Objective-C pointeur à l'Objective-C et aussi en transfère la propriété à l'ARC.

    L'ARC est responsable de renoncer à la propriété de l'objet.

Source: Numéro Sans Frais Comblé Types

32voto

Brad Larson Points 122629

Comme, dans ce cas précis, si vous êtes sur iOS, Apple recommande l'utilisation de UIColor et son -CGColor méthode pour retourner CGColorRef dans l' colors NSArray. Dans la Transition à l'ARC Notes de publication, sous la section "Le Compilateur Gère CF les Objets Retournés à Partir de Cacao Méthodes", il est indiqué que l'utilisation de la méthode -CGColor qui retourne un Fondement de Base de l'objet sera automatiquement traitée correctement par le compilateur.

Ainsi, ils suggèrent d'utiliser le code suivant:

CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
                                                 (id)[[UIColor lightGrayColor] CGColor], nil];

Notez qu'à partir de maintenant, Apple est l'exemple de code est manquant (id) en fonte que j'ai ci-dessus, qui est toujours nécessaire pour éviter une erreur de compilation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X