Правильное соединение для ARC?

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

Ответ 1

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

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

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

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

Ответ 2

Это правильная, непроникающая версия. Как вы говорите в комментариях: __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));
}

Ответ 3

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

Ответ 4

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

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