Как преобразовать CFStringRef в NSString?
Вопрос
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
Как я могу получить новый NSString
из aCFString
?
Решение
NSString и CFStringRef являются "бесплатными мостовыми соединениями", что означает, что вы можете просто ввести между ними тип.
Например:
CFStringRef aCFString = (CFStringRef)aNSString;
работает идеально и прозрачно. Точно так же:
NSString *aNSString = (NSString *)aCFString;
Предыдущий синтаксис был для MRC. Если вы используете ARC, новый синтаксис приведен ниже:
NSString *aNSString = (__bridge NSString *)aCFString;
тоже работает. Главное, на что следует обратить внимание, это то, что CoreFoundation будет часто возвращать объекты с +1 счетчиком ссылок, что означает, что они должны быть освобождены (все функции форматирования CF [Type] Create делают это).
Приятно то, что в Какао вы можете безопасно использовать autorelease или release для их освобождения.
Другие советы
Если вы используете ARC в последних версиях Mac OS X / Objective C, это <я> реально легко:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
Тем не менее, Xcode с радостью предупредит вас, когда вы попытаетесь позвонить по бесплатному мосту. CFString для NSString и предлагают автоматически обернуть его в CFBridgingRelease (), которую вы можете принять и позволить ей автоматически вставлять упаковщик, если вы нажмете эту опцию.
Они эквивалентны, так что вы можете просто привести CFStringRef:
NSString *aNSString = (NSString*)aCFString;
Для получения дополнительной информации см. Toll- Свободные мостовые типы .
На самом деле, вы не должны использовать Cocoa retain, release, autorelease для объектов Core Foundation в целом. Если вы используете сборщик мусора (пока только в Mac OS X), все вызовы retain, release, autorelease - это все no-ops. Отсюда утечки памяти.
от Apple .apple.com / макинтош / библиотека / документация / Какао / Концептуальное / GarbageCollection / Статьи / gcCoreFoundation.html :
Важно оценить асимметрию между Базовой основой и Какао, где сохранение, высвобождение и авто-выпуск не допускаются. Если, например, у вас есть баланс CFCreate & # 8230; с выпуском или авто-выпуском вы утечете объект в среде сборки мусора:
NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment
И наоборот, использование CFRelease для освобождения объекта, ранее сохраненного вами с помощью retain, приведет к ошибке недостаточного подсчета ссылок.
<Ч>PS: не могу прокомментировать ответ Питера Хоси - извините за добавление моего собственного излишне.
Я добавлю, что вы можете не только перейти от CFString к NSString только с приведением типов, но и работать по-другому. Вы можете оставить сообщение CFStringCreateWithCString
, которое вам нужно выпустить позже. (CF использует Create
, где Cocoa использует alloc
, так что в любом случае вам нужно будет его освободить.)
Полученный код:
NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
У меня была проблема с ARC и счетом сохранения CFStrings. Использование ответа NilObjects с небольшим изменением отлично сработало для меня. Я просто добавил сохранил, например. Р>
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
Вы должны разыграть его:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
Вы можете использовать: с CFStringRef idc;
NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];