Correct bridging for ARC?

Stephan Keene picture Stephan Keene · Jul 25, 2011 · Viewed 22.3k times · Source

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];
}

Answer

Caffeine picture Caffeine · Jul 26, 2011

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.