2011-07-25 10 views
43

Mam klasę kategorii dla NSString.Prawidłowe pomost dla 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; 
} 

Czy używam poprawnych transferów mostów dla ARC i nowego LLVM?

Oryginalny kod:

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

Odpowiedz

43

Jak wspomniano w komentarzach, myślę, że to w porządku mówić o ARC i zawartości Automatic Reference Counting tutaj.

__autoreleasing nie jest przeznaczony do używania w ten sposób. Służy do przekazywania pośrednich referencji obiektów (NSError **, itp.). Zobacz 4.3.4 Passing to an out parameter by writeback.

Zgodnie z 3.2.4 Bridged casts, __bridge_transfer jest poprawny, ponieważ funkcja CFURLCreateStringByAddingPercentEscapes zwraca zatrzymany obiekt (ma w nazwie "create"). Chcesz, aby ARC przejęło własność zwróconego obiektu i wstaw zwolnienie (lub autorelease w tym przypadku), aby to zrównoważyć.

Oddanie __bridge za originalstring również jest poprawne, nie chcesz, aby ARC robił w tej sprawie coś specjalnego.

+0

Dziękuję - to pomogło niezmiernie. Chciałem tylko upewnić się, że moje rozumienie dokumentów zostało poprawnie zastosowane. –

+9

Mogę dodać, że użycie makra 'CFBridgingRelease()' sprawia, że ​​przesyłanie i używanie obiektów CFType jest łatwiejsze do odczytania - przynajmniej w moich oczach. na przykład 'NSData * imageData = CFBridgingRelease (ABPersonCopyImageData (osoba))' – monkeydom

28

To jest poprawna, nie wyciekająca wersja. Jak można powiedzieć w komentarzach: __bridge_transfer przeniesienia własności do NSObject(NSString) i zakładamy, że obiekt jest utrzymywany przez CF Framework (metoda CFURLCreateStringByAddingPercentEscapes zwrócić retained obiekt więc to, czego potrzebujemy) niż na obiekcie siebie nie chcemy wykonać dowolne zarządzanie pamięcią. Nadzieję, że pomoże 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

nr __autoreleasing niezbędny. Prawidłowa składnia ARC to po prostu:

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