views:

5789

answers:

4
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);

How can I get a new NSString from aCFString?

+6  A: 

They are equivalent, so you can just cast the CFStringRef:

NSString *aNSString = (NSString*)aCFString;

For more info, see Interchangeable Data Types.

Martin Cote
+24  A: 

NSString and CFStringRef are "Toll free bridged", meaning that you can simply typecast between them.

For example:

CFStringRef aCFString = (CFStringRef)aNSString;

works perfectly and transparently. Likewise:

NSString *aNSString = (NSString *)aCFString;

works as well. The key thing to note is that CoreFoundation will often return objects with +1 reference counts, meaning that they need to be released (all CF[Type]Create format functions do this).

The nice thing is that in Cocoa you can safely use autorelease or release to free them up.

NilObject
+2  A: 

I'll add that not only can you go from CFString to NSString with only a type-cast, but it works the other way as well. You can drop the CFStringCreateWithCString message, which is one fewer thing you need to release later. (CF uses Create where Cocoa uses alloc, so either way, you would have needed to release it.)

The resulting code:

NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedNSString, NULL) autorelease];
Peter Hosey
A: 

Actually, you shouldn't use Cocoa retain, release, autorelease on Core Foundation objects in generality. If you're using Garbage Collection (only on Mac OS X for now), those retain, release, autorelease calls are all no-ops. Hence memory leaks.

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

It is important to appreciate the asymmetry between Core Foundation and Cocoa—where retain, release, and autorelease are no-ops. If, for example, you have balanced a CFCreate… with release or autorelease, you will leak the object in a garbage collected environment:

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

Conversely, using CFRelease to release an object you have previously retained using retain will result in a reference count underflow error.


PS: can't seem to comment on Peter Hosey's answer - sorry for adding my own unnecessarily.

gavinbeatty