正确桥接ARC?

时间:2011-07-25 21:16:16

标签: objective-c automatic-ref-counting

我有一个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 个答案:

答案 0 :(得分:43)

正如评论中所提到的,我认为在这里讨论ARC和Automatic Reference Counting的内容是可以的。

__autoreleasing并不意味着像这样使用。它用于传递间接对象引用(NSError **等)。请参阅4.3.4 Passing to an out parameter by writeback

根据3.2.4 Bridged casts__bridge_transfer是正确的,因为CFURLCreateStringByAddingPercentEscapes函数返回一个保留对象(其名称中包含“create”)。您希望ARC获取返回对象的所有权并插入一个版本(或在这种情况下自动释放)以平衡这一点。

__bridge的{​​{1}}广告也是正确的,您不希望ARC对此做任何特别的事情。

答案 1 :(得分:28)

这是一个正确的,而不是泄漏的版本。 正如您在评论中所述:__bridge_transfer将所有权转移到NSObject (NSString)并假设该对象由CF Framework保留(方法CFURLCreateStringByAddingPercentEscapes返回{ {1}}对象所以这就是我们需要的) 而不是自我对象,我们不想执行任何内存管理。希望能帮助到你 FRA

retained

答案 2 :(得分:2)

-(NSString *) urlEncoded
{
    CFStringRef encodedCfStringRef = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'\"();@+$,%#[]% ",kCFStringEncodingUTF8 );
    NSString *endcodedString = (NSString *)CFBridgingRelease(encodedCfStringRef);
    return endcodedString;
}

答案 3 :(得分:0)

不需要__autoreleasing。正确的ARC语法就是:

- (NSString *)URLEncodedString
{
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                     (CFStringRef)self,
                                                                     NULL,
                                                                     (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                     kCFStringEncodingUTF8));
}