Как преобразовать 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 [Type] Create делают это).

Приятно то, что в Какао вы можете безопасно использовать авто-релиз или релиз, чтобы освободить их.


88
Если вы используете ARC, новый синтаксис приведения в этом случае теперь NSString * aNSString = (__bridge NSString *) aCFString
MikeG

6
Спасибо MikeG, мне пришлось сделать подобное для обратного преобразования: NSString * str = @ "abc"; CFStringRef cstrref = (__ bridge 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 retain, release, autorelease для объектов Core Foundation в целом. Если вы используете сборщик мусора (пока только в Mac OS X), все вызовы retain, release, autorelease - это все no-ops. Отсюда утечки памяти.

От 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.