Assume this code is compiled under ARC:
BOOL method(unsigned a)
{
NSString *string = [[NSString alloc] initWithCString:"hi"];
if (a & 1 == 1)
{
CFStringRef CF = (CFStringRef)CFBridgingRetain(string);
printf("%s", CFStringGetCStringPtr(CF, kCFStringEncodingUTF8));
CFRelease(CF);
}
}
Will string get over-released in this example? What if I did the reverse?
BOOL method(unsigned a)
{
CFStringRef string = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingUTF8);
if (a & 1 == 1)
{
NSString *ns = (NSString *)CFBridgingRelease(string);
printf("%s", CFStringGetCStringPtr(CF, kCFStringEncodingUTF8);
}
if (string)
CFRelease(string);
}
Your first snippet is correct. Your second one is wrong.
To fix the second snippet, replace this:
NSString *ns = (NSString *)CFBridgingRelease(string);
with this:
NSString *ns = (__bridge NSString *) string;
That’s because ns
isn’t taking ownership of the string, it’s just using it temporarily.
Alternatively, and this is what I try to do almost always, write code like this:
CFStringRef string = CFStringCreateWithCString(…);
NSString * ns = CFBridgingRelease(string);
if (a & 1 == 1)
{
… work with `ns`
}
// No `CFRelease`!
That is, get out of ‘CF space’ as quickly as possible and let ARC do all the heavy lifting.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"