2011-07-25 21 views
43

Tôi có một lớp danh mục cho NSString.Cầu nối đúng cho 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; 
} 

Tôi có sử dụng chuyển giao cầu chính xác cho ARC và LLVM mới không?

Mã gốc:

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

Trả lời

43

Như đã đề cập trong các ý kiến, tôi nghĩ rằng nó là tốt để nói về ARC và các nội dung của Automatic Reference Counting đây.

__autoreleasing không được sử dụng như vậy. Nó được sử dụng để truyền tham chiếu đối tượng gián tiếp (NSError **, v.v.). Xem 4.3.4 Passing to an out parameter by writeback.

Theo 3.2.4 Bridged casts, __bridge_transfer là chính xác vì hàm CFURLCreateStringByAddingPercentEscapes trả về đối tượng được giữ lại (nó có "tạo" trong tên của nó). Bạn muốn ARC sở hữu đối tượng được trả về và chèn một bản phát hành (hoặc tự động phát hành trong trường hợp này) để cân bằng điều này.

Đoạn __bridge cho originalstring cũng đúng, bạn không muốn ARC thực hiện bất kỳ điều gì đặc biệt về nó.

+0

Cảm ơn bạn - điều này đã giúp vô cùng. Tôi chỉ muốn chắc chắn rằng sự hiểu biết của tôi về các tài liệu đã được áp dụng một cách chính xác. –

+9

Tôi có thể thêm rằng sử dụng macro 'CFBridgingRelease()' làm cho việc truyền và tiêu thụ các đối tượng CFType dễ đọc hơn - ít nhất là trong mắt tôi. ví dụ. 'NSData * imageData = CFBridgingRelease (ABPersonCopyImageData (người))' – monkeydom

28

Đây là phiên bản chính xác, không bị rò rỉ. Như bạn nói trong các ý kiến: __bridge_transfer chuyển nhượng quyền sở hữu cho NSObject(NSString) và cho rằng đối tượng được giữ lại bởi CF Framework (phương pháp CFURLCreateStringByAddingPercentEscapes trả về một đối tượng retained vì vậy đây là những gì chúng ta cần) hơn về bản thân đối tượng chúng tôi không muốn để thực hiện bất kỳ quản lý bộ nhớ nào. Hy vọng nó giúp 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

Không __autoreleasing cần thiết. Cú pháp ARC chính xác chỉ đơn giản là:

- (NSString *)URLEncodedString 
{ 
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, 
                    (CFStringRef)self, 
                    NULL, 
                    (CFStringRef)@"!*'();:@&=+$,/?%#[]", 
                    kCFStringEncodingUTF8)); 
} 
Các vấn đề liên quan