Làm cách nào để chuyển đổi CFStringRef sang NSString?


169
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);

Làm thế nào tôi có thể nhận được một cái mới NSStringtừ aCFString?

Câu trả lời:


349

NSString và CFStringRef là "Toll free Bridged", nghĩa là bạn có thể chỉ cần gõ chữ giữa chúng.

Ví dụ:

CFStringRef aCFString = (CFStringRef)aNSString;

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

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;

làm việc tốt Điều quan trọng cần lưu ý là CoreFoundation sẽ thường trả về các đối tượng có số tham chiếu +1, nghĩa là chúng cần được phát hành (tất cả CF [Loại] Tạo các hàm định dạng thực hiện việc này).

Điều tuyệt vời là trong Cacao bạn có thể sử dụng autorelease hoặc phát hành một cách an toàn để giải phóng chúng.


88
Nếu bạn đang sử dụng ARC, cú pháp truyền mới cho trường hợp này hiện là 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 các bình luận. Cảm ơn.
Dan Rosenstark

17

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, điều đó thực sự 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 chuyển cầu miễn phí CFString sang NSString và đề nghị tự động gói nó trong CFBridgingRelease (), bạn có thể chấp nhận và để 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.


3
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 tăng số lượng giữ lại với CFBridgingRelease().
Cœur


4

Trên thực tế, bạn không nên sử dụng tính năng giữ lại, phát hành, tự động phát hành trên các đối tượng Core Foundation. Nếu bạn đang sử dụng Bộ sưu tập rác (hiện chỉ có trên Mac OS X), các cuộc gọi giữ lại, phát hành, tự động chạy đều là không có. Do đó bộ nhớ bị rò rỉ.

Từ Apple http://developer.apple.com/mac/l Library / documentation / Coloa / Contualual / GarbageCollection / Articles / gcCoreFoundation.html :

Điều quan trọng là phải đánh giá cao sự bất cân xứng giữa Core Foundation và Cốc Cốc trong đó việc giữ lại, phát hành và tự động là không có tác dụng. Ví dụ: nếu bạn đã cân bằng CFCreate, với bản phát hành hoặc tự động phát hành, bạn sẽ rò rỉ đối tượng trong 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 để giải phóng một đối tượng mà bạn đã giữ lại trước đó bằng cách sử dụng giữ lại sẽ dẫn đến lỗi tràn số tham chiếu.


Tái bút: dường như không thể bình luận về câu trả lời của Peter Hosey - xin lỗi vì đã thêm sự không cần thiết của riêng tôi.


3

Tôi sẽ nói thêm rằng bạn không chỉ có thể đi từ CFString sang NSString chỉ với một kiểu diễn viên, mà nó còn hoạt động theo cách khác. Bạn có thể bỏ CFStringCreateWithCStringtin nhắn, đó là một điều ít hơn bạn cần phát hành sau này. (CF sử dụng Createnơi Ca cao sử dụng alloc, do đó, dù sao đi nữa, bạn sẽ cần phải phát hành nó.)

Mã kết quả:

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

2

Tôi gặp vấn đề với ARC và số lượng CFStrings được giữ lại. Sử dụng câu trả lời của NilObjects với một tinh chỉnh nhỏ hoạt động hoàn hảo đối với tôi. Tôi chỉ thêm giữ lại, ví dụ.

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;

0

Bạn phải bỏ nó:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;

-3

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

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.