2011-07-25 22 views
43

Tengo una clase de categoría para NSString.¿Puenteo correcto para 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; 
} 

¿Estoy utilizando las transferencias de puente correctas para ARC y el nuevo LLVM?

El código original:

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

Respuesta

43

Como se ha mencionado en los comentarios, creo que está bien hablar de ARC y el contenido de Automatic Reference Counting aquí.

__autoreleasing no está destinado a ser utilizado de esa manera. Se usa para pasar referencias indirectas a objetos (NSError **, etc.). Ver 4.3.4 Passing to an out parameter by writeback.

De acuerdo con 3.2.4 Bridged casts, el __bridge_transfer es correcto ya que la función CFURLCreateStringByAddingPercentEscapes devuelve un objeto retenido (tiene "crear" en su nombre). Desea que ARC tome posesión del objeto devuelto e inserte una versión (o liberación automática en este caso) para equilibrar esto.

El modelo __bridge para originalstring es correcto, no desea que ARC haga algo especial al respecto.

+0

Gracias, esto ayudó inmensamente. Solo quería asegurarme de que mi comprensión de los documentos se aplicaba correctamente. –

+9

Podría agregar que el uso de la macro 'CFBridgingRelease()' hace que la transferencia y el consumo de objetos CFType sea mucho más fácil de leer, al menos en mi opinión. p.ej. 'NSData * imageData = CFBridgingRelease (ABPersonCopyImageData (persona))' – monkeydom

28

Esta es una versión correcta, sin fugas. Como se dice en los comentarios: __bridge_transfer transferencia de la propiedad a NSObject(NSString) y asume que el objeto es retenida por CF Framework (el método CFURLCreateStringByAddingPercentEscapes devolver un objeto retained así que esto es lo que necesitamos) que en el objeto mismo que no queremos para realizar cualquier gestión de memoria. Espero que ayuda Fra

-(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

Sin __autoreleasing necesario. La sintaxis ARC correcta es simple:

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