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];
}
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.
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));
}
-(NSString *) urlEncoded
{
CFStringRef encodedCfStringRef = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'\"();@+$,%#[]% ",kCFStringEncodingUTF8 );
NSString *endcodedString = (NSString *)CFBridgingRelease(encodedCfStringRef);
return endcodedString;
}
No __autoreleasing
necessary. The correct ARC syntax is simply:
- (NSString *)URLEncodedString
{
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
}