正确桥接ARC?
我有一个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; }
我是否使用ARC和新LLVM的正确桥接传输?
原代码:
- (NSString *)URLEncodedString NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8); return [encodedString autorelease]; }
正如在评论中提到的,我认为在这里谈论ARC和自动引用计数的内容是很好的。
__autoreleasing
并不意味着要这样使用。 它用于传递间接对象引用(NSError **等)。 请参阅4.3.4通过回写传递给out参数 。
根据3.2.4 Bridged casts , __bridge_transfer
是正确的,因为CFURLCreateStringByAddingPercentEscapes
函数返回一个保留的对象(它的名字中有“create”)。 您希望ARC获得所返回对象的所有权并插入一个版本(或者在这种情况下是autorelease)来平衡这一点。
originalstring
__bridge
也是正确的,你不希望ARC做任何特殊的事情。
这是一个正确的,没有泄漏的版本。 正如你在评论中所说: __bridge_transfer
将所有权转移给NSObject
(NSString)
并假定该对象由CF Framework
保留( CFURLCreateStringByAddingPercentEscapes
方法返回一个retained
对象,所以这是我们需要的),而不是自我对象,我们不想要执行任何内存pipe理。 希望它有助于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; }
没有__autoreleasing
必要的。 正确的ARC语法很简单:
- (NSString *)URLEncodedString { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); }