NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
Comment puis-je obtenir un nouveau NSString
de aCFString
?
NSString et CFStringRef sont "pontés sans frais", ce qui signifie que vous pouvez simplement transtyper entre eux.
Par exemple:
CFStringRef aCFString = (CFStringRef)aNSString;
fonctionne parfaitement et de manière transparente. Également:
NSString *aNSString = (NSString *)aCFString;
La syntaxe précédente était pour MRC. Si vous utilisez ARC, la nouvelle syntaxe de transtypage est la suivante:
NSString *aNSString = (__bridge NSString *)aCFString;
fonctionne aussi bien. L'important, c'est que CoreFoundation renvoie souvent les objets avec un nombre de références +1, ce qui signifie qu'ils doivent être libérés (toutes les fonctions de format CF [Type] Create le font).
La bonne chose est que dans Cocoa, vous pouvez utiliser en toute sécurité autorelease ou release pour les libérer.
Si vous utilisez ARC dans des versions récentes de Mac OS X/Objective C, c’est réal facile:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
Cependant, Xcode vous avertira volontiers lorsque vous essayez de passer sans pont de CFString à NSString et vous propose de l'envelopper automatiquement dans CFBridgingRelease (), ce que vous pouvez accepter et de le laisser insérer automatiquement l'enveloppe pour vous si vous cliquez sur l'option.
Ils sont équivalents, vous pouvez donc lancer le CFStringRef:
NSString *aNSString = (NSString*)aCFString;
Pour plus d’informations, voir Types de ponts sans frais .
En fait, vous ne devriez pas utiliser Cocoa Retenir, Libérer, Autorelease sur les objets Core Foundation en général. Si vous utilisez Garbage Collection (uniquement sous Mac OS X pour le moment), les appels conservés, validés, à libération automatique ne sont pas autorisés. D'où des fuites de mémoire.
Il est important d’apprécier l’asymétrie entre Core Foundation et Cocoa, où la rétention, la libération et la libération automatique ne nécessitent aucune opération. Si, par exemple, vous avez équilibré un CFCreate… avec release ou autorelease, vous fuyez l'objet dans un environnement collé:
NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment
Inversement, l'utilisation de CFRelease pour libérer un objet que vous avez précédemment retenu à l'aide de retenue entraînera une erreur de dépassement du nombre de références.
PS: n'arrive pas à commenter la réponse de Peter Hosey - désolé d'avoir ajouté la mienne inutilement.
J'ajouterai que non seulement vous pouvez passer de CFString à NSString avec uniquement une transtypage, mais que cela fonctionne également dans l'autre sens. Vous pouvez supprimer le message CFStringCreateWithCString
, ce qui est une chose de moins à libérer ultérieurement. (CF utilise Create
alors que Cocoa utilise alloc
, de toute façon, vous auriez besoin de le libérer.)
Le code résultant:
NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
J'avais un problème avec ARC et le nombre de retenues de CFStrings. Utilisation de NilObjects répondre avec un léger Tweak a fonctionné parfaitement pour moi. Je viens d'ajouter retenu par exemple.
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
Vous devez le lancer:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;