2009-03-12 11 views
157
NSString *aNSString; 
CFStringRef aCFString; 
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding); 
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL); 

Wie kann ich eine neue NSString von aCFString bekommen?Wie konvertiert man CFStringRef in NSString?

Antwort

331

NSString und CFStringRef sind "gebührenfrei überbrückt", was bedeutet, dass Sie einfach zwischen ihnen tippen können.

Zum Beispiel:

CFStringRef aCFString = (CFStringRef)aNSString; 

funktioniert perfekt und transparent. Gleichfalls:

NSString *aNSString = (NSString *)aCFString; 

Die vorherige Syntax war für MRC. Wenn Sie ARC verwenden, lautet die neue Casting-Syntax wie folgt:

funktioniert auch. Das Wichtigste ist, dass CoreFoundation oft Objekte mit +1 Referenzzählwerten zurückgibt, was bedeutet, dass sie freigegeben werden müssen (alle CF [Type] Create Format-Funktionen tun dies).

Das Schöne ist, dass Sie in Cocoa sicher Autorelease oder Freigabe verwenden können, um sie freizugeben.

+85

Wenn Sie mit ARC, die neue Casting-Syntax für diesen Fall nun NSString * aNSString = (__bridge NSString *) aCFString – MikeG

+6

Dank MikeG hatte ich Ähnliches gilt für die umgekehrte Umwandlung zu tun: NSString * str = @ "ABC"; CFStringRef cstref = (__ Brücke CFStringRef) str; – KomodoDave

+2

@NilObject Bitte aktualisieren Sie Ihre Antwort, um ARC einzuschließen, damit die Suchenden die Kommentare nicht überprüfen müssen. Vielen Dank. –

12

Sie sind gleichwertig, so dass Sie nur die CFStringRef Stimmen:

NSString *aNSString = (NSString*)aCFString; 

Für mehr Informationen, Toll-Free Bridged Types sehen.

3

Ich füge hinzu, dass Sie nicht nur von CFString zu NSString mit nur einem Typ-Cast gehen können, aber es funktioniert auch andersherum. Sie können die Nachricht löschen, was eine Sache weniger ist, die Sie später veröffentlichen müssen. (CF verwendet Create wo Cocoa alloc verwendet, so oder so, hätte man benötigt, es zu veröffentlichen.)

Der resultierende Code:

NSString *escapedString; 
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease]; 
4

Eigentlich sollten Sie nicht Cocoa behalten verwenden, Freigabe, Autofreigabe auf Core Foundation-Objekten allgemein. Wenn Sie Garbage Collection verwenden (derzeit nur für Mac OS X), sind diese Retain-, Release- und AutoRelease-Aufrufe alle No-Ops. Daher Speicherlecks.

von Apple http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html:

Es ist wichtig, dass die Asymmetrie zwischen Core Foundation und Cocoa-where behalten, Release und Autorelease zu schätzen sind No-ops. Wenn zum Beispiel haben Sie eine CFCreate ausgewogen ... mit Release oder Autorelease, werden Sie das Objekt in einer Müll gesammelt Umgebung entweichen:

NSString *myString = (NSString *)CFStringCreate...(...); 
// do interesting things with myString... 
[myString release]; // leaked in a garbage collected environment 

Umgekehrt CFRelease mit einem Objekt zu lösen haben Sie vorher behalten retained Verwendung führt in einem Referenzzähler-Unterlauffehler.

PS: kann Peter Hoseys Antwort nicht kommentieren - tut mir leid, dass ich meine eigene unnötigerweise hinzugefügt habe.

2

Ich hatte ein Problem mit ARC und die Retain-Anzahl von CFStrings. Die Verwendung von NilObjects mit einer kleinen Optimierung funktionierte perfekt für mich. Ich habe gerade beibehalten, zB.

CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString; 
0

Sie haben zu werfen:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName; 
14

Wenn Sie ARC verwenden in neueren Versionen von Mac OS X/Objective C, es ist echte einfach:

NSString *happyString = (NSString *)CFBridgingRelease(sadString); 

Xcode wird Sie jedoch gerne warnen, wenn Sie versuchen, die Bridge CFString an NSString zu gebührenfrei anzubieten und automatisch das Wrapper in CFBridgingRelease() anzubieten. können Sie akzeptieren und lassen Sie es automatisch den Wrapper für Sie einfügen, wenn Sie auf die Option klicken.

+1

Ich bin mir nicht sicher, aber ich denke '(__bridge NSString *)' ist genug: es hat keinen Sinn, die Retain-Anzahl mit 'CFBridgingRelease()' zu erhöhen. –

-3

Sie können Folgendes verwenden: Mit CFStringRef idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc]; 
Verwandte Themen