2011-10-25 20 views
6

Supongamos que estoy recibiendo una cadena C de alguna función:Gestión de memoria: de NSString stringWithCString: codificación:

char * mystring = SomeCFunction(...);

y soy propietario de esta cadena (soy responsable de liberar cuando he terminado)

Si, en Objective-C, creo una NSString * usando:

NSString * mynsstring = [NSString stringWithCString:mystring 
              encoding:NSUTF8StringEncoding]; 

¿Todavía soy responsable de liberar la cadena original de C?

Supongo que la respuesta es sí, pero no puedo encontrar una respuesta definitiva en la documentación, y la funcionalidad del método opuesto (cStringUsingEncoding), aunque sensible, me da pausa, porque maneja el cString liberando para ti.

Si la respuesta es sí, ¿entonces también soy responsable de asegurarme de no liberar la cadena c antes de terminar de usar el NSString *, o la función copia la cadena por mí? Lo pregunto porque la documentación para stringWithCString dice:

Devuelve una cadena que contiene los bytes en una matriz C dado, interpretado según una codificación determinada.

Lo que todavía me deja preguntándome si realmente copió los bytes, o si solo los señala internamente (y básicamente estoy haciendo un molde).

Respuesta

8

Copia los bytes.

Si no desea que se copien los bytes, puede usar - (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag.

Si utiliza - (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding, o cualquier método básico como stringWithCString:encoding: que a su vez llame a este método de bajo nivel, los bytes se copian.

+0

¡Ah! Eres increíble. ¡Gracias! Aceptaré la respuesta después de que hayan transcurrido los 6 minutos restantes en el temporizador de bloqueo de aceptación. – Steve

+0

Esto debería estar en los documentos –

+0

@ AndréFratelli Le sugiero que envíe un comentario (hay un enlace en la parte inferior de cada página de la documentación en línea) así que Apple agrega esto ;-) – AliSoftware

3

La API no tiene idea de dónde proviene el puntero que pasa, por lo que no sabe cómo apropiarse de él. Podría ser de malloc(), pero también podría ser un puntero interior o de mmap(), en cuyo caso free() no funcionará. Entonces, la API se ve obligada a copiar los datos.

El único momento en que puede pasar la propiedad de un búfer C a una API Cocoa es si la API le permite indicar que necesita ser liberado. Eche un vistazo a -[NSData initWithBytesNoCopy:length:freeWhenDone:], por ejemplo.

+0

+1, Sí, eso hace mucho de sentido para mí ... a veces solo con los documentos de Apple fueron un poco más explícitos sobre este tipo de cosas, en lugar de dejarte deducir esas cosas por ti mismo. En este caso, me hizo dudar lo suficiente como para pensar que debería preguntar. – Steve

+0

Bastante justo. Archive un error y solicite que se lo llame explícitamente en la documentación. – kperryua