43

我有一个 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];
}
4

4 回答 4

43

正如评论中提到的,我认为在这里谈论ARC和Automatic Reference Counting的内容很好。

__autoreleasing不应该这样使用。它用于传递间接对象引用(NSError** 等)。请参阅4.3.4 通过 writeback 传递给 out 参数

根据3.2.4 Bridged casts,这__bridge_transfer是正确的,因为CFURLCreateStringByAddingPercentEscapes函数返回一个保留对象(它的名称中有“create”)。您希望 ARC 获得返回对象的所有权并插入一个释放(或在本例中为自动释放)以平衡这一点。

for的__bridge演员表originalstring也是正确的,您不希望 ARC 对此做任何特别的事情。

于 2011-07-25T23:38:26.633 回答
28

这是一个正确的,不泄漏的版本。正如您在评论中所说:__bridge_transfer将所有权转移给NSObject (NSString)并假设该对象被保留CF Framework(该方法CFURLCreateStringByAddingPercentEscapes返回一个retained对象,所以这是我们需要的)而不是我们不想执行任何内存管理的 self 对象。希望它可以帮助弗拉

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
           (__bridge CFStringRef)self,
           NULL,
           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
           CFStringConvertNSStringEncodingToEncoding(encoding));
}
于 2012-02-16T10:45:00.177 回答
2
-(NSString *) urlEncoded
{
    CFStringRef encodedCfStringRef = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'\"();@+$,%#[]% ",kCFStringEncodingUTF8 );
    NSString *endcodedString = (NSString *)CFBridgingRelease(encodedCfStringRef);
    return endcodedString;
}
于 2013-01-09T08:26:04.287 回答
0

没有__autoreleasing必要。正确的 ARC 语法很简单:

- (NSString *)URLEncodedString
{
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                     (CFStringRef)self,
                                                                     NULL,
                                                                     (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                     kCFStringEncodingUTF8));
}
于 2014-11-04T12:27:32.197 回答