2012-05-02 292 views
2
- (NSString*)encodeURL:(NSString *)string 
{ 
    NSString *newString = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); 

    if (newString) 
    { 
     return newString; // <-- potential leak here 
    } 

    return @""; 
} 

我不熟悉CFType(除了知道它們是什麼)。這是我從互聯網上獲得的代碼,爲了讓它在ARC中工作而不得不花費一些時間。我收到了潛在的泄漏警告,我不知道如何解決它。建議?ios阻止潛在的內存泄漏

回答

8

是的,這是一個內存泄漏。你的意思是使用CFBridgingRelease()而不是__bridge

CFURLCreateStringByAddingPercentEscapes創建的對象有一個額外的保留,因爲它包括Create。您需要將該對象轉移到ARC,並讓它知道添加額外的版本,這就是CFBridgingRelease()所做的。

NSString *newString = 
    CFBridgingRelease(
     CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
               (__bridge CFStringRef)string, 
               NULL, 
               CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"),   
               kCFStringEncodingUTF8)); 

您確實使用__bridge作爲傳入的字符串,因爲您沒有將其傳送到Core Foundation。你只是要求核心基金會使用它,而ARC繼續擁有它。當你「轉讓」所有權時,你一般的意思是「這個對象曾經是核心基金會,現在它是ARC」(反之亦然)。這就是newString

我換了長NS-to-CF編碼函數,結果只是爲了縮短它。

0

返回字符串的自動釋放的版本,CFStringRef可以轉換爲NSString,反之亦然,這也意味着你可以把它像一個正常的NSString,從而自動釋放它(如果你有興趣在此,你應該閱讀有關FoundationCore Foundation的部分之間的免費橋接)

+0

這是ARC代碼(因爲它使用'__bridge')。您不能在ARC代碼中手動自動釋放。 –

+1

@RobNapier Argh,你的孩子和你新的閃亮的東西^^對不起,完全錯過了那部分。 – JustSid

0

另一種方式是像這樣使用__bridge_transfer代替__bridge的:

NSString *newString = (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); 

看更多的資料在這個問題:Correct bridging for ARC?