Où et comment __pont
J'ai besoin de quelques conseils sur __bridge
-ing dans iOS.
J'espère que la SSCCE1 ci-dessous va vous expliquer le problème mieux que je peux dans les mots, mais j'ai besoin de savoir comment je peux convertir un void*
à un NSMutableArray*
; qui __bridge
la variation doit être utilisé (Voir le commentaire dans le code).
Lu sur les différents ponts, j'en ai déduit que j'aurais besoin de __bridge_transfer
mais puis-je recevoir un EXC_BAD_ACCESS sur addObject:
En fin de compte, j'aimerais avoir un tableau de la CGPoints
dans le CGPath
après CGPathApply
a été appelé.
#import <Foundation/Foundation.h>
void _processPathElement(void* info, const CGPathElement* element)
{
NSMutableArray *array = (/* WHAT BRIDGE HERE */ NSMutableArray*) info;
switch (element->type)
{
case kCGPathElementMoveToPoint:
case kCGPathElementAddLineToPoint:
{
CGPoint point = element->points[0];
[array addObject:[NSValue valueWithCGPoint:point]];
break;
}
default:
break;
}
}
int main(int argc, char *argv[])
{
@autoreleasepool
{
//Create path
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, 1, 0);
CGPathAddLineToPoint(path, NULL, 1, 1);
CGPathAddLineToPoint(path, NULL, 0, 1);
CGPathCloseSubpath(path);
NSMutableArray *pathPoints = [NSMutableArray array];
CGPathApply(path, &pathPoints, _processPathElement);
NSLog(@"Points:%@", pathPoints);
}
}
1: SSCCE
- Je ne comprends pas. J'ai simplement utilisé
__bridge
comme suggéré par Xcode. Et votre programme compile. - Ou vous êtes à la recherche pour cela,
__bridge
transferts d'un pointeur entre Objective-C et le Fondement de Base avec aucun transfert de propriété.__bridge_retained
ouCFBridgingRetain
jette un Objectif-C pointeur vers un Fondement de Base de pointeur et aussi des transferts de propriété pour vous. Vous êtes responsable de l'appel CFRelease ou une fonction liée à renoncer à la propriété de l'objet.__bridge_transfer
ouCFBridgingRelease
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. - le commentaire) Il n'est pas juste une affaire d'obtenir le code à compiler. J'ai besoin de la mémoire pour être correctement maintenu de sorte que j'ai accès à
pathPoints
pour laNSLog
- commentaire) j'ai lu que sur un autre site, et en déduit que j'aurais besoin de
__bridge_transfer
mais puis-je recevoir un EXC_BAD_ACCESS suraddObject:
Vous devez vous connecter pour publier un commentaire.
La documentation sur l'utilisation du pont mots clés peuvent être trouvés ici. Plus précisément, je tiens à souligner §3.2.4:
Le pointeur que vous êtes passés dans (
void*
) est un non retainable de type pointeur, alors que votre NSMutableArray est un retainable type de pointeur. Cette__bridge_retained
tout de suite. La question est donc, à__bridge
ou à__bridge_transfer
?__bridge_transfer
est généralement utilisé lorsque vous voulez que l'Objective-C pointeur à partir d'une méthode qui retourne une FC Objet qui a été retenu. Par exemple, CFStringCreateWithFormat sera de retour d'une retenue CFString, mais si vous voulez un NSString, vous devez__bridge_transfer
entre eux. Cela rendra l'ARC de libération de l'objet que FC a conservé le cas échéant. Par exemple,NSString* str = (__bridge_transfer NSString*) CFStringCreateWithFormat(...);
Votre code n'est pas fait, vous n'avez pas besoin de se mêler à la propriété. Votre méthode principale est le contrôle de sa gestion de la mémoire, et qui est tout simplement de passer une référence à une méthode qu'il appelle (bien qu'indirectement, mais c'est tout à l'intérieur de la portée de la main). En tant que tel, vous devez utiliser
__bridge
.Mais attendez, quand j'utilise __pont, mon code d'accès à la mémoire d'erreurs!?
Ah, c'est un problème avec le code que vous avez posté, et n'est pas liée à la transition de discussion. Vous devez passer une
void*
à CGApplyPath, pour votre fonction de traitement_processPathElement
. Ce que vous êtes de passage estNSMutableArray**
.Lorsque vous refonte de la
NSMutableArray*
, vous êtes réellement en jetant unNSMutableArray**
. Ce sera la cause de l'infâme EXC_BAD_ACCESS. Vous avez besoin de passer le pointeur lui-même, et non pas un pointeur vers un pointeur. Mais,CGPathApply(path, pathPoints, _processPathElement)
ne fonctionnera pas, vous ne pouvez pas passer unNSMutableArray*
comme unvoid*
. Ce dont vous avez besoin (ironiquement), est un pont. Pour les mêmes raisons que précédemment, tous vous avez besoin est__bridge
. Voir ci-dessous le code, avec la bonne ponts en lieu, et fonctionne comme prévu:Cela permettra d'imprimer:
CFBridg*
variantes est souvent plus clair (pour certains d'entre nous, de toute façon).Je ne suis pas vraiment sûr de savoir pourquoi cela fonctionne, mais j'ai trouvé la solution:
Si quelqu'un peut expliquer pourquoi cela fonctionne et confirmer qu'il n'y a pas (/sont) tout les fuites de mémoire, je lui en serais reconnaissant