2010-04-07 66 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)];