2011-07-25 69 views
43

我有一個NSString的類別類。正確橋接ARC?

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

回答

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替換爲originalstring也是正確的,您不希望ARC對此做任何特殊處理。

+0

謝謝你 - 這非常有幫助。我只是想確保我對文檔的理解能夠正確應用。 –

+9

我可以補充一點,使用CFBridgingRelease()宏可以使CFType對象的傳輸和消費更容易閱讀 - 至少在我眼中。例如'NSData * imageData = CFBridgingRelease(ABPersonCopyImageData(person))' – monkeydom

28

這是一個正確的,沒有泄漏的版本。 當你在評論中說:__bridge_transfer轉移所有權NSObject(NSString)並假定對象由CF Framework保留(方法CFURLCreateStringByAddingPercentEscapes返回一個retained對象,所以這是我們所需要的) 比我們不希望自己的對象上執行任何內存管理。希望它可以幫助 弗拉

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { 
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, 
      (__bridge CFStringRef)self, 
      NULL, 
      (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", 
      CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 
2
-(NSString *) urlEncoded 
{ 
    CFStringRef encodedCfStringRef = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'\"();@+$,%#[]% ",kCFStringEncodingUTF8); 
    NSString *endcodedString = (NSString *)CFBridgingRelease(encodedCfStringRef); 
    return endcodedString; 
} 
0

沒有必要__autoreleasing。正確的ARC語法很簡單:

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