Как преобразовать CFStringRef в NSString? - PullRequest
163 голосов
/ 12 марта 2009
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);

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

Ответы [ 8 ]

344 голосов
/ 12 марта 2009

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

Например:

CFStringRef aCFString = (CFStringRef)aNSString;

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

NSString *aNSString = (NSString *)aCFString;

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

NSString *aNSString = (__bridge NSString *)aCFString;

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

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

16 голосов
/ 01 марта 2013

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

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

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

12 голосов
/ 12 марта 2009

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

NSString *aNSString = (NSString*)aCFString;

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

4 голосов
/ 16 апреля 2010

На самом деле, вы не должны использовать 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 голосов
/ 13 марта 2009

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

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

NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
2 голосов
/ 06 июля 2012

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

CFStringRef cfstringRef = (__bridge_retained  CFStringRef)aNsString;
0 голосов
/ 17 октября 2013

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

NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];
0 голосов
/ 29 октября 2012

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

CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
...