3

我有一个相当大的 NSData(或 NSMutableData,如果需要)对象,我想从中取出一小块并留下其余部分。由于我正在处理大量 NSData 字节,因此我不想制作大副本,而只是截断现有字节。基本上:

  • NSData *source: <我想丢弃的几个字节> + <我想保留的大块字节>
  • NSData *destination: <我想保留的大块字节>

NSMutableData 中有截断方法,但它们只截断它的结尾,而我想截断开头。我的想法是用以下方法做到这一点:

请注意,我在原始帖子中使用了错误的(复制)方法。我已经编辑并修复了它

- (const void *)bytes

- initWithBytesNoCopy:length:freeWhenDone:

但是,我试图弄清楚如何用这些来管理内存。我猜这个过程会是这样的(我把????s放在我不知道该怎么做的地方):

// Get bytes
const unsigned char *bytes = (const unsigned char *)[source bytes];

// Offset the start
bytes += myStart;

// Somehow (m)alloc the memory which will be freed up in the following step
?????

// Release the source, now that I've allocated the bytes
[source release];

// Create a new data, recycling the bytes so they don't have to be copied
NSData destination = [[NSData alloc]
                      initWithBytesNoCopy:bytes
                      length:myLength
                      freeWhenDone:YES];

谢谢您的帮助!

4

4 回答 4

5

这是你想要的吗?

NSData *destination = [NSData dataWithBytes:((char *)source.bytes) + myStart
                                     length:myLength];

我知道您说过“我不想制作大副本”,但这只会与您getBytes:length:在示例中使用的副本相同,所以这对您来说可能没问题。

还有replaceBytesInRange:withBytes:length:,您可以像这样使用它:

[source setLength:myStart + myLength];
[source replaceBytesInRange:NSMakeRange(0, myStart)
                  withBytes:NULL
                     length:0];

但是文档没有说明该方法是如何工作的(没有性能特征),并且source需要是 NSMutableData。

于 2010-06-16T02:17:30.410 回答
4

根据具体情况,解决方案可能会有所不同。我将假设您需要一个方法来返回NSData具有指定范围的自动释放对象:

- (NSData *)getSubData:(NSData *)source withRange:(NSRange)range
{
    UInt8 bytes[range.length];
    [source getBytes:&bytes range:range];
    NSData *result = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
    return [result autorelease];
}

当然,您可以将其设为类方法并将其放入某种“utils”类或在 NSData 上创建扩展...

于 2010-08-05T01:03:29.473 回答
3

如果要避免复制内存块,可以使用 将dataWithBytesNoCopy旧缓冲区保留一定的偏移量。在此示例中,我们“删除”前 2 个字节:

source = [NSData dataWithBytesNoCopy:(char*)source.bytes + 2 length:source.length - 2];

为了示例简单起见,边界检查被跳过,请在方便时添加。在 iOS 2.0 及更高版本中可用。

于 2013-01-29T16:26:15.480 回答
2

还有一种NSData方法-[subdataWithRange:(NSRange)range]可以解决问题。我不知道性能是什么样的(我想它会复制一两个,但我不确定)。它可以像这样使用:

NSData *destination = [source subdataWithRange:NSMakeRange(0, lengthIWant)];
于 2014-03-14T16:10:15.593 回答