2010-02-27 4 views
26

Posso aggiungere facilmente byte a un'istanza NSMutableData utilizzando il metodo appendData, tuttavia non vedo alcun metodo simile per la rimozione dei dati? Sto trascurando qualcosa o devo creare un nuovo oggetto e copiare solo i byte di cui ho bisogno?NSMutableData rimuove byte?

risposta

71

consultare la documentazione del seguente metodo:

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

Apple dice chiaramente le seguenti:

Se la lunghezza del campo non è uguale a replacementLength, il ricevitore è ridimensionati a ospitare i nuovi byte. Qualsiasi intervallo di byte nel ricevitore viene spostato per accogliere i nuovi byte . È quindi possibile passare NULL per replacementBytes e 0 per replacementLength per eliminare i byte in il ricevitore nell'intervallo dell'intervallo. È possibile inoltre sostituire un intervallo (che potrebbe essere a lunghezza zero) con più byte di della lunghezza dell'intervallo, che ha l'effetto di inserimento (o "sostituire alcuni e inserirne altri").

Per rimuovere 10 byte dalla fine, usare:

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

Potrebbe anche essere fatto tramite replaceBytesInRange, ma è in realtà molto più veloce, perché i byte non sono realmente rimossi. Invece, solo la variabile di dimensione interna viene modificata e NSMutableData si comporterà come se i byte fossero stati rimossi. IOW, questa è un'operazione O (1) (ciò significa che ci vorrà sempre altrettanto tempo per eseguire, indipendentemente da quanti byte rimuovi), ed è molto veloce.

Per rimuovere 10 byte dalla parte anteriore, utilizzare:

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

Per rimuovere 10 byte nel mezzo (ad esempio dopo 20 byte), uso:

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

replaceBytesInRange è O (n) operazione, però. Ciò significa non importa quanto tempo ci vuole per rimuovere 100 byte, ci vorrà il doppio del tempo per rimuovere 200 byte e così via. È ancora abbastanza veloce e limitato solo dal throughput della memoria del tuo computer (RAM). Se si dispone di 10 MB di dati e si rimuove 1 MB dalla parte anteriore, vengono copiati 9 MB per riempire il vuoto della MB appena rimossa. Quindi la velocità dell'operazione dipende dalla velocità con cui il sistema può spostare 9 MB di RAM da un indirizzo a un altro.E questo di solito è abbastanza veloce, a meno che non si tratti di oggetti NSMutableData contenenti centinaia di MB.

+0

Questa è una grande risposta, anche se è derivata da una risposta che ha molto meno upvotes ed è ora irrilevante. Potresti rivederlo per renderlo una risposta autonoma? +1 –

+1

@Yar: Certo, perché no. Ho rimosso il riferimento all'altra risposta. – Mecki

+0

In qualche modo sono tornato a questa risposta oggi, cercavo "Puoi anche sostituire un intervallo (che potrebbe essere di lunghezza zero) con più byte della lunghezza dell'intervallo, che ha l'effetto di inserimento (o" sostituisci alcuni e inserisci altro ")." Tangenziale ma rilevante. Grazie! –

3

Dal NSMutableData è colmato con CFMutableDataRef numero verde, è possibile utilizzare i CFDataDeleteBytes() funzione:

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

Fai attenzione. In questo percorso si trovano i problemi di prestazioni. Se stai modificando relativamente poche volte o lavori con un po 'di dati, non è un grosso problema. Qualunque cosa più grande o frequente o sensibile alle prestazioni, considera l'utilizzo di una struttura dati ottimizzata di qualche tipo. – bbum

+0

Grazie, ha funzionato alla grande. Come fai a sapere che i dati di NSMutable sono "a pagamento senza pedaggio" con CFMutableDataRef? Non vedo alcuna menzione di questo nei documenti NSMutableData? – Kyle

+0

Se si guarda la sezione "Panoramica" dei documenti NSMutableData http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSMutableData_Class/Reference/NSMutableData.html lo vedrai menzionato nel secondo paragrafo –

1

Se i dati che si desidera rimuovere è alla fine, si può usare

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

o con l'obj-c sintassi 2,0

NSMutableDataInstance.length -= n; 

per qualcosa di più complicato di quello che consiglierei di manipolare i dati grezzi.

+0

Grazie per il suggerimento! Sto comunque cercando di rimuovere dal fronte :) – Kyle

0

Vedo che questo thread ha la risposta, ma ciò potrebbe essere utile aggiungere. Per rimuovere tutti i byte da NSMuttableData, è possibile creare nuovi dati e copiarlo originale:

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

Questa grande opera.