2012-05-02 5 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 @""; 
} 

Я не знаком с CFTypes (кроме знания того, что они есть). Это код, который я получил из Интернета, и ему пришлось немного окунуться, чтобы заставить его работать в ARC. Я получаю потенциальное предупреждение о утечке, и я не уверен, как это исправить. Предложения?ios, препятствующий потенциальной утечке памяти

ответ

8

Да, это утечка памяти. Вы хотели использовать CFBridgingRelease(), а не __bridge.

Объект, созданный CFURLCreateStringByAddingPercentEscapes, имеет дополнительную удержание на нем, так как он включает в себя Create. Вам необходимо перенести этот объект в ARC, сообщив ему, чтобы добавить дополнительную версию, вот что делает CFBridgingRelease().

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

Вы используете __bridge для переданного в строке, потому что вы не перенося его в Основной фонд. Вы просто просите Core Foundation использовать его, пока ARC продолжает владеть им. Когда вы «передаете» право собственности, вы обычно подразумеваете «этот объект, который использовался для Core Foundation, а теперь это ARC» (или наоборот). Это то, что происходит с newString.

Я поменял длинную функцию кодирования NS-to-CF, чтобы результат был короче.

0

Вернуть autoreleased версию строки, CFStringRef могут быть преобразованы в NSString и наоборот, что также означает, что вы можете рассматривать его как обычный NSString и, таким образом, autorelease его (если вы заинтересованы в этом, вы должны прочитать о бесплатное мостовое соединение между частями Foundation и Core 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?

Смежные вопросы