iOS pont vs bridge_transfer
Je suis confus avec bridge
et bridge_transfer
, est-ce correct?
-(void)getData{
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSString *name;
for ( int i = 0; i < [allPeople count]; i++ )
{
name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty);
}
CFRelease(addressBook);
allPeople = nil;
}
Est-il quelqu'un qui peut m'expliquer comment les utiliser?
Vous devez vous connecter pour publier un commentaire.
Si vous avez automatique de comptage de références (ARC) est activée, le code est correct.
Il y a deux
__bridge_transfer
dans vos déclarations. En conséquence, la propriété de créé CFObjects seront transférés à NSObjects. Si vous avez de l'ARC en marche, ils sera libéré automatiquement. Si vous avez utilisé__bridge
à la place de ces 2 états, vous aurez besoin d'appeler explicitementCFRelease
pour libérer CFObjects créé par le*Copy
API.La
__bridge
déclaration est également correcte. Parce que vous êtes le référencement d'un NSObject en CF API. Vous n'êtes pas le transfert de la propriété, de sorte que l'ARC va le libérer.Il est très très simple, Lorsque vous utilisez l'ARC (automatic reference counting) le compilateur va prendre soin de compter le nombre d'objets se faire remarquer par vos variables. Quand le comte passe à 0, l'objet est automatiquement dealocated. DONC, pour les choses qui viennent à partir d'un faible niveau de la structure, comme le noyau de la fondation, le compilateur ne sait pas quoi faire. Si vous utilisez le PONT, si vous voulez juste pour dire au compilateur "ignorer celui-ci, je le sors quand j'en ai besoin". ou Pont de transfert si vous voulez dire "considérer comme un objet et de le libérer lorsque la référence passe à 0).
Lorsque vous faites cela, vous créez une copie que dans des circonstances normales, doit être libéré par un "CFRelease":
Toutefois par l'ajout de ce fait, vous êtes transfert la propriété à un objectif-c objet:
De sorte que le NSArray sera géré par l'ARC.
Noter que, comme JRG mentionne, pour ce faire:
N'affecte pas l'objet nouvellement créé, de toute façon, mais au lieu de l'original que vous n'avez toujours manuellement la sortie: (C'est facile à dire, parce que ces méthodes ont généralement le créer ou copie mots-clés dans leurs noms)
Quelque chose qui ne se fait pas dans votre code, mais vous devez être prudent avec est que la libération de cœur de la fondation des objets qui sont NULS avec CFRelease provoquera une erreur. Comme Paul le mentionne dans son commentaire.
[nil release]
ce qui est bien,CFRelease(NULL)
provoque une erreur.NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
transfère la propriété de la matrice qui est retourné. Cela n'a rien à voir avecaddressBook
. Plutôt,addressBook
doit être libéré, car il a été créé avec une "créer" la méthode (ABAddressBookCreate
). Sinon, il sera de fuite.Luis Oscar je suis encore à ma compréhension de l'ARC, mais je crois carnet d'adresses ne doivent CFRelease. L'ARC n'est pas la gestion de carnet d'adresses. NSArray *allPeople est géré par ARC via l' __pont_transfert fonte d'indication, et il est créé une copie de l'original. Sans le CFRelease, le carnet d'adresses de fuite.
Un edit: je crois que l'appel de CFRelease sur un nul objet ne cause à l'application de crash