objective-c nsdata nsmutabledata

objective c - NSMutableData eliminar bytes?



objective-c nsdata (4)

¿Puedo agregar bytes a una instancia de NSMutableData fácilmente usando el método appendData , sin embargo, no veo ningún método similar para eliminar datos? ¿Estoy pasando por alto algo, o necesito crear un nuevo objeto y copiar solo los bytes que necesito?


Dado que NSMutableData es un puente gratuito con CFMutableDataRef, puede usar la función CFDataDeleteBytes ():

NSMutableData *data = ... CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4));


Por favor vea la documentación del siguiente método:

- (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)replacementBytes length:(NSUInteger)replacementLength

Apple dice claramente lo siguiente:

Si la longitud del rango no es igual a la longitud de reemplazo, el receptor se redimensiona para acomodar los nuevos bytes. Los bytes que se encuentran más allá del rango en el receptor se desplazan para acomodar los nuevos bytes. Por lo tanto, puede pasar NULL para replacementBytes y 0 para replacementLength para eliminar bytes en el receptor dentro del rango. También puede reemplazar un rango (que podría ser de longitud cero) con más bytes que la longitud del rango, lo que tiene el efecto de inserción (o "reemplazar algunos e insertar más").

Para eliminar 10 bytes del final, use:

[data setLength:[data length] - 10];

También podría hacerse a través de replaceBytesInRange, pero de hecho es mucho más rápido, porque los bytes no se eliminan realmente. En cambio, solo se cambia la variable de tamaño interno y NSMutableData se comportará como si se hubieran eliminado los bytes. IOW, esta es una operación O (1) (eso significa que siempre tomará el mismo tiempo, independientemente de la cantidad de bytes que elimine), y es muy rápida.

Para eliminar 10 bytes del frente, use:

[data replaceBytesInRange:NSMakeRange(0, 10) withBytes:NULL length:0];

Para eliminar 10 bytes en el medio (por ejemplo, después de 20 bytes), use:

[data replaceBytesInRange:NSMakeRange(20, 10) withBytes:NULL length:0];

Sin embargo, replaceBytesInRange es una operación O (n). Eso significa que no importa cuánto tiempo se tarda en eliminar 100 bytes, tardará el doble en eliminar 200 bytes y así sucesivamente. Todavía es bastante rápido y solo está limitado por el rendimiento de la memoria de su computadora (RAM). Si tiene 10 MB de datos y elimina 1 MB de la parte frontal, se copiarán 9 MB para llenar el vacío de los MB que se acaban de eliminar. Por lo tanto, la velocidad de la operación depende de qué tan rápido puede mover su sistema 9 MB de RAM de una dirección a otra. Y esto suele ser lo suficientemente rápido, a menos que se trate de objetos NSMutableData que contengan cientos de MB.


Si los datos que desea eliminar están al final, puede usar

[NSMutableDataInstance setLength:[NSMutableDataInstance length] - n];

o con la sintaxis de obj-c 2.0

NSMutableDataInstance.length -= n;

para algo más complicado que eso, recomiendo manipular los datos en bruto.


Veo que este hilo tiene la respuesta, pero sin embargo, esto podría ser un complemento valioso. Para eliminar todos los bytes de NSMuttableData, puede crear nuevos datos y copiarlos al original:

[myData setData:[NSData dataWithBytes:NULL length:0]];

Esto funciona muy bien.