Как преобразовать CFStringRef в NSString?

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

Как я могу получить новый NSString из aCFString?

Ответ 1

NSString и CFStringRef - это "Безплатный мостик", что означает, что вы можете просто выводить между ними.

Например:

CFStringRef aCFString = (CFStringRef)aNSString;

работает отлично и прозрачно. Точно так же:

NSString *aNSString = (NSString *)aCFString;

Предыдущий синтаксис был для MRC. Если вы используете ARC, новый синтаксис кастинга выглядит следующим образом:

NSString *aNSString = (__bridge NSString *)aCFString;

работает также. Главное отметить, что CoreFoundation будет часто возвращать объекты с числом ссылок +1, что означает, что их нужно освободить (все функции CF [Type] Create format делают это).

Самое приятное, что в Cocoa вы можете безопасно использовать autorelease или release, чтобы освободить их.

Ответ 2

Если вы используете ARC в последних версиях Mac OS X/Objective C, it real легко:

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

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

Ответ 3

Они эквивалентны, поэтому вы можете просто наложить CFStringRef:

NSString *aNSString = (NSString*)aCFString;

Для получения дополнительной информации см. Неограниченные мостовые типы.

Ответ 4

На самом деле, вы не должны использовать Cocoa сохранить, освободить, autorelease на объектах Core Foundation в общности. Если вы используете Garbage Collection (только на Mac OS X на данный момент), те, которые сохраняют, освобождают, звонки с автоматической переадресацией, не являются операциями. Следовательно, утечки памяти.

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

Важно оценить асимметрию между Core Foundation и Cocoa, где сохранение, освобождение и автоматическое оповещение не являются операциями. Если, например, вы сбалансировали CFCreate... с выпуском или autorelease, вы пропустите объект в среде сбора мусора:

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

И наоборот, использование CFRelease для освобождения объекта, который вы ранее сохранили с помощью сохранения, приведет к ошибке недооценки счетчика ссылок.


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

Ответ 5

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

Полученный код:

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

Ответ 6

У меня возникла проблема с ARC и удержанием CFStrings. Использование ответа NilObjects с небольшой настройкой идеально подходит для меня. Я только добавил, добавил, например.

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;

Ответ 7

Вам нужно бросить его:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;

Ответ 8

Вы можете использовать: с CFStringRef idc;

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];