Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct bridging for ARC?

I have a category class for NSString.

@implementation NSString (URLEncode)  - (NSString *)URLEncodedString {     __autoreleasing NSString *encodedString;      NSString *originalString = (NSString *)self;         encodedString = (__bridge_transfer NSString * )             CFURLCreateStringByAddingPercentEscapes(NULL,                                 (__bridge CFStringRef)originalString,                                 NULL,                                 (CFStringRef)@"!*'();:@&=+$,/?%#[]",                                 kCFStringEncodingUTF8);     return encodedString; } 

Am I using the correct bridge transfers for ARC and the new LLVM?

The original code:

- (NSString *)URLEncodedString     NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,                                 (CFStringRef)self,                                 NULL,                                 (CFStringRef)@"!*'();:@&=+$,/?%#[]",                                 kCFStringEncodingUTF8);     return [encodedString autorelease]; } 
like image 582
Stephan Keene Avatar asked Jul 25 '11 21:07

Stephan Keene


2 Answers

As mentioned in the comments, I think it's fine to talk about ARC and the contents of Automatic Reference Counting here.

__autoreleasing is not meant to be used like that. It's used for passing indirect object references (NSError**, etc). See 4.3.4 Passing to an out parameter by writeback.

According to 3.2.4 Bridged casts, the __bridge_transfer is correct as the CFURLCreateStringByAddingPercentEscapes function returns a retained object (it has "create" in its name). You want ARC to take ownership of the returned object and insert a release (or autorelease in this case) to balance this out.

The __bridge cast for originalstring is correct too, you don't want ARC to do anything special about it.

like image 97
Caffeine Avatar answered Oct 01 '22 13:10

Caffeine


This is a correct, not leaking version. As you say in the comments: __bridge_transfer transfer the ownership to NSObject (NSString) and assume that the object is retained by CF Framework (the method CFURLCreateStringByAddingPercentEscapes return a retained object so this is what we need) than on the self object we don't want to perform any memory management. Hope it helps Fra

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {     return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,            (__bridge CFStringRef)self,            NULL,            (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",            CFStringConvertNSStringEncodingToEncoding(encoding)); } 
like image 29
Punty Avatar answered Oct 01 '22 12:10

Punty