Consider this simple method; it's a category on NSString.
- (NSString *)stringByUrlEncoding
{
CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
NSString *returnString = (__bridge NSString *)newString;
CFRelease(newString);
return returnString;
}
Its job is to turn =
into %3D
, etc. for URL encoding, but that's not relevant to this question.
A few questions about memory management:
After CFRelease(newString);
is called, I can still po newString
in the debugger and see the string. Does this mean it's not getting deallocated properly?
When I pass casted CFStringRefs to arguments of CFURLCreateStringByAddingPercentEscapes, (like (CFStringRef)self
, for example) I believe that I do NOT need to store those to a variable and then CFRelease them due to "toll-free bridging". Is this correct?
Does the answer to #2 change if it's a CGImageRef, not a CFStringRef? Why does CGImageRef have its own CGImageRelease function, but there's no CFStringRelease method?
To make sure my understanding of __bridge_transfer
is correct, is this modified code identical?
- (NSString *)stringByUrlEncoding
{
CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8);
NSString *returnString = (__bridge_transfer NSString *)newString;
// CFRelease(newString);
return returnString;
}
As to your questions:
1) You don't have enough information to know if newString
should have been deallocated. For instance, if no character replacement was actually needed, it would be reasonable for CFURLCreateStringByAddingPercentEscapes
to return you the equivalent of [self retain]
; This is but one example. The broader point is "you can't know." The normal approach here would be to use Instruments to look for heap growth and leaks. For more information, google "retainCount useless" (I won't rehash it here.)
2) Yes.
3) CGImageRef
is not toll-free bridged, however, as I understand it, CFRetain
and CFRelease
should work. The difference between CFRelease
and CGImageRelease
here is that the parameter to CFRelease
must not be NULL
, whereas CGImageRelease
will tolerate NULL
parameters.
4) __bridge_transfer
is the appropriate annotation to use here. This "transfers" the +1 retain count from the side that ARC doesn't handle to the side it does handle. Put differently, __bridge_transfer
just tells ARC that it will need to create a release
call for this pointer, even through it never generated a retain
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With