新 NSData 与旧 NSData 维护字节范围

发布于 2024-08-28 05:34:46 字数 1117 浏览 10 评论 0原文

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

  • NSData *来源:<我想要几个字节 丢弃> + <大块字节 I 想要保留>
  • NSData *目的地:<大的 我想保留的字节块>

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];

感谢您的帮助!

I have a fairly large NSData (or NSMutableData if necessary) object which I want to take a small chunk out of and leave the rest. Since I'm working with large amounts of NSData bytes, I don't want to make a big copy, but instead just truncate the existing bytes. Basically:

  • NSData *source: < a few bytes I want to
    discard > + < big chunk of bytes I
    want to keep >
  • NSData *destination: < big
    chunk of bytes I want to keep >

There are truncation methods in NSMutableData, but they only truncate the end of it, whereas I want to truncate the beginning. My thoughts are to do this with the methods:

Note that I used the wrong (copying) method in the original posting. I've edited and fixed it

- (const void *)bytes

and

- initWithBytesNoCopy:length:freeWhenDone:

However, I'm trying to figure out how to manage memory with these. I'm guessing the process will be like this (I've placed ????s where I don't know what to do):

// 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];

Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瑾兮 2024-09-04 05:34:46

这是你想要的吗?

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。

Is this what you want?

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

I know you said "I don't want to make a big copy," but this only does the same copy you were doing with getBytes:length: in your example, so this may be okay to you.

There's also replaceBytesInRange:withBytes:length:, which you might use like this:

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

But the doc's don't say how that method works (no performance characteristics), and source needs to be an NSMutableData.

明月夜 2024-09-04 05:34:46

根据具体情况,解决方案可能会有所不同。我假设您需要一个方法来返回具有指定范围的自动释放的 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 的扩展...

depending on the context, the solutions can be different. I will assume that you need a method that would return an autoreleased NSData object with the specified range:

- (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];
}

Of course, you can make it a class method and put it into some kind of "utils" class or create an extension over NSData...

醉南桥 2024-09-04 05:34:46

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

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

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

If you want to avoid copying memory blocks, you can use the dataWithBytesNoCopy to keep the old buffer with a certain offset. In this example we "remove" the first 2 bytes:

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

For the sake of example simplicity, boundary check is skipped, please add it as it convenient for you.
Available in iOS 2.0 and later.

月亮坠入山谷 2024-09-04 05:34:46

还有一个 NSData 方法 -[subdataWithRange:(NSRange)range] 也可以做到这一点。我不知道表演是什么样的(我想象它会做一两个副本,但我不确定)。它可以像这样使用:

NSData *destination = [source subdataWithRange:NSMakeRange(0, lengthIWant)];

There's also an NSData method -[subdataWithRange:(NSRange)range] that could do the trick. I have no idea what the performance looks like (I'd imagine it does a copy or two, but I don't know for certain). It can be used like:

NSData *destination = [source subdataWithRange:NSMakeRange(0, lengthIWant)];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文