Правильный мост для ARC? - PullRequest
43 голосов
/ 26 июля 2011

У меня есть класс категории для 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 ]

43 голосов
/ 26 июля 2011

Как уже упоминалось в комментариях, я думаю, что хорошо говорить об ARC и содержании Автоматический подсчет ссылок здесь.

__autoreleasing не предназначен для такого использования. Он используется для передачи косвенных ссылок на объекты (NSError ** и т. Д.). См. 4.3.4. Передача в выходной параметр обратной записи .

В соответствии с 3.2.4. Приведение с мостом , __bridge_transfer является правильным, так как функция CFURLCreateStringByAddingPercentEscapes возвращает сохраненный объект (в его имени "create") Вы хотите, чтобы ARC вступила во владение возвращенным объектом и вставила релиз (или в данном случае в авто-релиз), чтобы сбалансировать это.

Правило __bridge для originalstring тоже верно, вы не хотите, чтобы ARC делал с ним что-то особенное.

28 голосов
/ 16 февраля 2012

Это правильная, не текущая версия. Как вы говорите в комментариях: __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));
}
2 голосов
/ 09 января 2013
-(NSString *) urlEncoded
{
    CFStringRef encodedCfStringRef = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)self,NULL,(CFStringRef)@"!*'\"();@+$,%#[]% ",kCFStringEncodingUTF8 );
    NSString *endcodedString = (NSString *)CFBridgingRelease(encodedCfStringRef);
    return endcodedString;
}
0 голосов
/ 04 ноября 2014

Нет __autoreleasing необходимо.Правильный синтаксис ARC просто:

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