Як перетворити CFStringRef в NSString?


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

Як я можу отримати новий NSStringвід aCFString?

Відповіді:


349

NSString та CFStringRef - це "безкоштовні мости", тобто ви можете просто набрати між ними.

Наприклад:

CFStringRef aCFString = (CFStringRef)aNSString;

працює ідеально та прозоро. Аналогічно:

NSString *aNSString = (NSString *)aCFString;

Попередній синтаксис був для MRC. Якщо ви використовуєте ARC, новий синтаксис кастингу такий:

NSString *aNSString = (__bridge NSString *)aCFString;

працює також. Ключове, що слід зазначити, це те, що CoreFoundation часто повертає об'єкти з +1 посиланнями, тобто їх потрібно випустити (всі CF [Тип] Створити форматні функції роблять це).

Приємно те, що в Какао можна сміливо використовувати автовипуск або випуск, щоб звільнити їх.


88
Якщо ви використовуєте ARC, новий синтаксис кастингу для цього випадку тепер є NSString * aNSString = (__bridge NSString *) aCFString
MikeG

6
Спасибі MikeG, мені довелося зробити подібне для зворотного перетворення: NSString * str = @ "abc"; CFStringRef cstrref = (__ міст CFStringRef) str;
KomodoDave

2
@NilObject, будь ласка, оновіть свою відповідь, щоб включити ARC, щоб пошукові користувачі не повинні перевіряти коментарі. Дякую.
Дан Розенстарк

17

Якщо ви використовуєте ARC в останніх версіях Mac OS X / Objective C, це так реальна легко:

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

Однак, Xcode з радістю попередить вас, коли ви намагатиметесь отримати безкоштовний міст CFString до NSString та запропонує автоматично обернути його у CFBridgingRelease (), який ви можете прийняти і дозволити автоматично вставити обгортку для вас, якщо натиснути цю опцію.


3
Я не впевнений, але я думаю, що (__bridge NSString *)цього достатньо: немає сенсу збільшувати кількість утримань CFBridgingRelease().
Cœur


4

Насправді, ви не повинні використовувати Cocoa зберігати, випускати, автовипускати на об'єктах Core Foundation взагалі. Якщо ви використовуєте Garbage Collection (лише зараз на Mac OS X), ці виклики зберігати, відпускати та автоматично випускати - це не потрібно. Звідси протікає пам'ять.

Від Apple http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html :

Важливо оцінити асиметрію між базовим фондом та какао - там, де утримання, вивільнення та автоматичне вивільнення відсутні. Якщо, наприклад, ви врівноважили CFCreate… з випуском або автоматичною випуском, ви просочите об’єкт у середовищі, зібраному зі сміттям:

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

І навпаки, використання CFRelease для випуску об'єкта, який ви раніше зберегли за допомогою функції retain, призведе до помилки під потоком помилки підрахунку.


PS: не можу коментувати відповідь Пітера Хосі - вибачте за те, що я додав власну.


3

Додам, що ви не тільки можете перейти з CFString до NSString лише з типом, але це працює і іншим способом. Ви можете скинути CFStringCreateWithCStringповідомлення, що є однією меншою справою, яку потрібно опублікувати пізніше. (CF використовує Createтам, де використовується какао alloc, тому в будь-якому випадку вам потрібно було б його випустити.)

Отриманий код:

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

2

У мене виникла проблема з ARC і кількість рахунків CFStrings. Використання відповіді NilObjects з невеликим настроєм працювало для мене ідеально. Я щойно додав збережений напр.

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;


-3

Ви можете використовувати: З CFStringRef idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.