Proper memory management with CFStringRef and CFRelease

Consider this simple method; This is the category on NSString.

- (NSString *)stringByUrlEncoding { CFStringRef newString = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8); NSString *returnString = (__bridge NSString *)newString; CFRelease(newString); return returnString; } 

Its task is to convert = to %3D , etc. for URL encoding, but this is not the case.

A few questions about memory management:

  • After calling CFRelease(newString); I can still po newString in the debugger and see the line. Does this mean that he is not being released properly?

  • When I pass CFStringRefs to the arguments of CFURLCreateStringByAddingPercentEscapes (like (CFStringRef)self , for example), I find that I DO NOT need to store them for the variable and then CFRelease them because of the "free bridge" Is this correct?

  • Does the response change to # 2 if it is a CGImageRef and not a CFStringRef? Why does CGImageRef have its own function CGImageRelease, but there is no CFStringRelease method?

  • To make sure my understanding of __bridge_transfer 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; } 
+6
source share
1 answer

Regarding your questions:

1) You do not have enough information to find out if newString should be canceled. For example, if character replacement was not really necessary, it would be wise for CFURLCreateStringByAddingPercentEscapes return the equivalent of [self retain] ; This is just one example. The broader question is "you cannot know." The usual approach here would be to use tools to find heap growth and leaks. For more google information, "saveCount is useless" (I will not rephrase it here.)

2) Yes.

3) CGImageRef not a bridge, but, as I understand it, CFRetain and CFRelease should work. The difference between CFRelease and CGImageRelease here is that the CFRelease parameter CFRelease not be NULL , while CGImageRelease will tolerate NULL parameters.

4) __bridge_transfer is a suitable annotation for use here. This "carries" the +1 counter on the side that ARC does not process on the side that it processes. In other words, __bridge_transfer simply tells ARC that it will need to create a release call for this pointer, even retain will never be generated through it.

+2
source

All Articles