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

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

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


person papr    schedule 12.03.2009    source источник


Ответы (8)


NSString и CFStringRef являются «бесплатными мостами», что означает, что вы можете просто приводить типы между ними.

Например:

CFStringRef aCFString = (CFStringRef)aNSString;

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

NSString *aNSString = (NSString *)aCFString;

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

NSString *aNSString = (__bridge NSString *)aCFString;

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

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

person NilObject    schedule 12.03.2009
comment
Если вы используете ARC, новый синтаксис приведения для этого случая теперь NSString *aNSString = (__bridge NSString *)aCFString - person MikeG; 15.12.2011
comment
Спасибо MikeG, мне пришлось сделать то же самое для обратного преобразования: NSString *str=@abc; CFStringRef cstrref=(__bridge CFStringRef)str; - person KomodoDave; 18.01.2012
comment
@NilObject, пожалуйста, обновите свой ответ, включив в него ARC, чтобы поисковикам не приходилось проверять комментарии. Спасибо. - person Dan Rosenstark; 24.06.2012

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

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

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

person clearlight    schedule 01.03.2013
comment
Я не уверен, но думаю, что (__bridge NSString *) достаточно: нет смысла увеличивать счетчик удержания с помощью CFBridgingRelease(). - person Cœur; 06.12.2015

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

NSString *aNSString = (NSString*)aCFString;

Дополнительные сведения см. в разделе Бесплатные мостовые типы .

person Martin Cote    schedule 12.03.2009

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

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

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

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

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


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

person gavinbeatty    schedule 15.04.2010

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

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

NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
person Peter Hosey    schedule 13.03.2009

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

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;
person dloomb    schedule 05.07.2012

Вы должны разыграть его:

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
person Vincent    schedule 29.10.2012

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

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