2010-04-07 105 views
2

我有一个相当大的NSData(或NSMutableData,如有必要)对象,我想从中取出一小块剩余的。由于我正在处理大量的NSData字节,因此我不想创建大副本,而只是截断现有字节。基本上是:新的NSData与旧的NSData维护字节范围

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

NSMutableData中有截断方法,但它们只截断它的末尾,而我想截断开始。我的想法是这样做的方法:

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

- (const void *)bytes 

- initWithBytesNoCopy:length:freeWhenDone: 

不过,我想弄清楚如何使用这些管理内存。我猜的过程是这样的(我已经放在????地方我不知道该怎么做):

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

感谢您的帮助!

+0

我想这是更多的malloc问题? – umop 2010-04-20 22:18:30

回答

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

但DOC的不说方法是如何工作的(无性能),并source需求是一个NSMutableData。

+0

+1用于解决我所遇到的(完全无关的)问题。 :) – Kalle 2010-07-16 19:37:46

+0

我刚刚意识到我使用的getBytes正在制作副本。我在想这是(const void *)字节的几个访问器之一。我已经适当地编辑了我的代码。对困惑感到抱歉。关于你的答案,不幸的是没有。我试图回收对象本身中的数据以用于其他对象,然后处理引用对象。 – umop 2010-08-05 13:26:21

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的扩展...

+0

我不得不编辑我的帖子。我打算使用(const void *)字节而不是getBytes:range。 – umop 2010-08-05 13:28:57

+0

取代????你的帖子的一部分,你可以使用像这样的smth:\t \t \t'memcpy(myNewByteArrayOfNewSize,bytes,[source length] - myStart);'.....我希望我没有搞乱任何指数 – Nick 2010-08-05 18:14:39

+0

但这将做一个副本。我正在寻找回收由字节指向的数据块,而不是复制它。基本上,我需要以某种方式保持块的mallocated时NSData *源不可避免地释放它。 – umop 2010-08-06 01:29:28

2

如果您想避免复制内存块,您可以使用dataWithBytesNoCopy来保留具有特定偏移量的旧缓冲区。在这个例子中,我们“删除”第2个字节:

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

例如简单起见,边界检查被跳过,请其添加为你方便。 Available in iOS 2.0及更高。

2

还有一个NSData方法-[subdataWithRange:(NSRange)range]可以做的伎俩。我不知道表现是怎样的(我想它会做一两个副本,但我不确定)。它可以使用像:

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