Como converter o CFStringRef em NSString?
Pergunta
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
Como posso conseguir um novo NSString
a partir de aCFString
?
Solução
O NSString e o CFStringRef são "Toll Free Bridged", o que significa que você pode simplesmente digitar entre eles.
Por exemplo:
CFStringRef aCFString = (CFStringRef)aNSString;
Funciona perfeitamente e transparentemente. Da mesma maneira:
NSString *aNSString = (NSString *)aCFString;
A sintaxe anterior foi para MRC. Se você estiver usando o ARC, a nova sintaxe de fundição é a seguinte:
NSString *aNSString = (__bridge NSString *)aCFString;
funciona também. A principal coisa a observar é que o CoreFoundation geralmente retorna objetos com +1 contagens de referência, o que significa que eles precisam ser lançados (todos os funções de formato de CF [Type] fazem isso).
O bom é que, no cacau, você pode usar com segurança o AutoRelease ou lançar para libertá -los.
Outras dicas
Se você está usando o ARC em versões recentes do Mac OS X/Objetivo C, é real fácil:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
No entanto, o Xcode o avisará com prazer quando você tentar cobrar o CFString de ponte gratuito para o NSString e se oferecer para envolvê -lo automaticamente no CFBRIDGINGRELEASENEase (), que você pode aceitar e deixá -lo inserir automaticamente o invólucro para você se clicar na opção.
Eles são equivalentes, então você pode simplesmente lançar o CFStringRef:
NSString *aNSString = (NSString*)aCFString;
Para mais informações, veja Tipos de ponte gratuitos gratuitos.
Na verdade, você não deve usar o cacau reter, liberar, o autorlease nos objetos principais da fundação na generalidade. Se você estiver usando a coleta de lixo (apenas no Mac OS X por enquanto), elas retêm, liberem as chamadas de autorlease são todas as opa. Portanto, vazamentos de memória.
É importante apreciar a assimetria entre fundamento central e cacau-onde retém, libera e autorlease são ninguém. Se, por exemplo, você equilibrar um CFCreate ... com liberação ou autorlease, você vazará o objeto em um ambiente coletado de lixo:
NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment
Por outro lado, o uso do CFRELEASE para liberar um objeto que você retido anteriormente usando retenção resultará em um erro de sub -fluxo de contagem de referência.
PS: Parece que não consigo comentar sobre a resposta de Peter Hosey - desculpe por adicionar o meu próprio desnecessariamente.
Acrescentarei que você não apenas pode ir do CFString para o NSString com apenas um tipo de tipo, mas também funciona para o outro lado. Você pode soltar o CFStringCreateWithCString
Mensagem, que é uma coisa menor que você precisa ser lançado mais tarde. (CF usa Create
onde o cacau usa alloc
, de qualquer maneira, você precisaria lançá -lo.)
O código resultante:
NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
Eu estava tendo um problema com o ARC e a contagem de retenção do CFStrings. Usando o Nilobjects Responder com um ligeiro ajuste funcionou perfeito para mim. Acabei de adicionar retida, por exemplo.
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
Você tem que lançar:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
Você pode usar: com cfstringRef IDC;
NSString *sId = [NSString stringWithFormat:@"%@", (NSString*)idc];