2009-03-12 34 views

Trả lời

331

NSString và CFStringRef là "Toll miễn phí cầu nối", có nghĩa là bạn có thể chỉ cần gõ giữa chúng.

Ví dụ:

CFStringRef aCFString = (CFStringRef)aNSString; 

hoạt động hoàn hảo và minh bạch. Tương tự:

NSString *aNSString = (NSString *)aCFString; 

Cú pháp trước là dành cho MRC. Nếu bạn đang sử dụng ARC, cú pháp truyền mới như sau:

NSString *aNSString = (__bridge NSString *)aCFString; 

cũng hoạt động. Điều quan trọng cần lưu ý là CoreFoundation sẽ thường trả về các đối tượng với số lượng tham chiếu +1, có nghĩa là chúng cần được giải phóng (tất cả các chức năng định dạng CF [Type] Create đều làm điều này).

Điều tốt đẹp là ở Cocoa bạn có thể sử dụng tự động phát hành một cách an toàn hoặc phát hành để giải phóng chúng.

+85

Nếu bạn đang sử dụng ARC, cú pháp đúc mới cho trường hợp này hiện đang NSString * aNSString = (__bridge NSString *) aCFString – MikeG

+6

Cảm ơn MikeG, tôi đã phải làm tương tự cho việc chuyển đổi ngược lại: NSString * str = @ "abc"; CFStringRef cstrref = (__ cầu CFStringRef) str; – KomodoDave

+2

@NilObject vui lòng cập nhật câu trả lời của bạn để bao gồm ARC để người tìm kiếm không phải kiểm tra nhận xét. Cảm ơn. –

12

Họ là tương đương, vì vậy bạn chỉ có thể cast CFStringRef:

NSString *aNSString = (NSString*)aCFString; 

Mọi chi tiết, thấy Toll-Free Bridged Types.

3

Tôi sẽ thêm rằng bạn không chỉ có thể chuyển từ CFString sang NSString chỉ với kiểu truyền, mà còn hoạt động theo cách khác. Bạn có thể thả thông báo CFStringCreateWithCString, đó là một điều ít bạn cần phải giải phóng sau này. (CF sử dụng Create nơi Cocoa sử dụng alloc, vì vậy một trong hai cách, bạn sẽ cần thiết để giải phóng nó.)

Mã kết quả:

NSString *escapedString; 
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease]; 
4

Trên thực tế, bạn không nên sử dụng Cocoa giữ, phát hành, autorelease về các đối tượng nền tảng lõi trong tổng quát. Nếu bạn đang sử dụng Garbage Collection (chỉ có trên Mac OS X bây giờ), những cuộc gọi giữ lại, phát hành, tự động gọi là tất cả các hoạt động không có. Do đó rò rỉ bộ nhớ.

Từ Apple http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html:

Điều quan trọng là đánh giá cao sự bất đối xứng giữa Core Foundation và Cocoa-nơi lưu giữ, phát hành, và autorelease không-ops. Nếu, ví dụ, bạn đã cân bằng một CFCreate ... với phát hành hoặc autorelease, bạn sẽ bị rò rỉ các đối tượng trong một môi trường thu gom rác:

NSString *myString = (NSString *)CFStringCreate...(...); 
// do interesting things with myString... 
[myString release]; // leaked in a garbage collected environment 

Ngược lại, sử dụng CFRelease để phát hành một đối tượng bạn đã từng giữ lại sử dụng giữ lại sẽ cho kết quả trong một lỗi tràn tính tham chiếu.


PS: dường như không thể nhận xét về câu trả lời của Peter Hosey - xin lỗi vì đã thêm của riêng tôi một cách không cần thiết.

2

Tôi gặp sự cố với ARC và số lượng lưu giữ của CFStrings. Sử dụng NilObjects trả lời với một chút tinh chỉnh làm việc hoàn hảo cho tôi. Tôi chỉ cần thêm vào giữ lại ví dụ.

CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString; 
0

Bạn phải cast nó:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName; 
14

Nếu bạn đang sử dụng ARC trong các phiên bản gần đây của Mac OS X/Objective C, nó thực dễ dàng:

NSString *happyString = (NSString *)CFBridgingRelease(sadString); 

Tuy nhiên, Xcode sẽ vui vẻ cảnh báo bạn khi bạn cố gắng thu phí cầu miễn phí CFString để NSString và đề nghị tự động bọc nó trong CFBridgingRelease(), mà bạn có thể chấp nhận và cho phép nó tự động chèn trình bao bọc cho bạn nếu bạn nhấp vào tùy chọn.

+1

Tôi không chắc chắn, nhưng tôi nghĩ '(__bridge NSString *)' là đủ: không có điểm nào trong việc gia tăng số lần giữ lại với 'CFBridgingRelease()'. –

-3

Bạn có thể sử dụng: Với id CFStringRef;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc]; 
Các vấn đề liên quan