web-dev-qa-db-ja.com

NSMutableDataはバイトを削除しますか?

appendDataメソッドを使用してNSMutableDataインスタンスにバイトを簡単に追加できますが、データを削除するための同様のメソッドが表示されませんか?何かを見落としているのですか、それとも新しいオブジェクトを作成して必要なバイトだけをコピーする必要がありますか?

27
Kyle

次の方法のドキュメントを参照してください。

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

Appleは明確に次のように述べています。

範囲の長さがreplacementLengthと等しくない場合、レシーバーは新しいバイトに対応するようにサイズ変更されます。レシーバーの範囲を超えたバイトは、新しいバイトに対応するためにシフトされます。したがって、replacementBytesにNULLを渡し、replacementLengthに0を渡して、範囲範囲内のレシーバーのバイトを削除できます。範囲(長さがゼロの場合もあります)を範囲の長さよりも多くのバイトに置き換えることもできます。これにより、挿入(または「一部を置き換えてさらに挿入」)の効果があります。

末尾から10バイトを削除するには、次を使用します。

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

ReplaceBytesInRangeを介して実行することもできますが、バイトが実際には削除されないため、実際にははるかに高速です。代わりに、内部サイズ変数のみが変更され、NSMutableDataはバイトが削除されたかのように動作します。 IOW、これはO(1)操作(つまり、削除するバイト数に関係なく、実行に常に同じ時間がかかることを意味します)であり、非常に高速です。

フロントから10バイトを削除するには、次を使用します。

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

途中(20バイト後など)の10バイトを削除するには、次を使用します。

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

replaceBytesInRangeはO(n)操作ですが、100バイトの削除にどれだけ時間がかかっても、200バイトの削除には2倍の時間がかかります。非常に高速で、コンピュータのメモリ(RAM)のスループットによってのみ制限されます。10MBのデータがあり、前面から1 MBを削除すると、9 MBがコピーされ、削除されたばかりのMBのギャップが埋められます。操作は、システムが9MBのRAMをあるアドレスから別のアドレスに移動できる速度によって異なります。数百MBを含むNSMutableDataオブジェクトを処理しない限り、これは通常十分に高速です。

72
Mecki

NSMutableDataはCFMutableDataRefと無料でブリッジされるため、CFDataDeleteBytes()関数を使用できます。

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

削除したいデータが最後にある場合は、

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

またはobj-c2.0構文を使用

NSMutableDataInstance.length -= n;

それよりも複雑な場合は、生データを操作することをお勧めします。

1
Jared Pochtar

このスレッドに答えがあるようですが、それでもこれは価値のある追加になる可能性があります。 NSMuttableDataからすべてのバイトを削除するには、新しいデータを作成して元のデータにコピーします。

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

これはうまくいきます。

0
Gossamer